From 30d10c60d2d436baa8b6118f34c6575e16966b04 Mon Sep 17 00:00:00 2001 From: Michael Date: Sat, 2 Sep 2023 15:52:53 +0000 Subject: [PATCH] Channels for audio, video and images --- database.sql | 1 + doc/database/db_post-engagement.md | 17 ++--- src/Model/Contact.php | 11 +++ src/Model/Post/Engagement.php | 39 ++++++++-- src/Module/Conversation/Channel.php | 44 ++++++++++-- static/dbstructure.config.php | 1 + view/lang/C/messages.po | 108 +++++++++++++++++----------- 7 files changed, 160 insertions(+), 61 deletions(-) diff --git a/database.sql b/database.sql index d5bc05faa6..aa2b27eeb4 100644 --- a/database.sql +++ b/database.sql @@ -1307,6 +1307,7 @@ CREATE TABLE IF NOT EXISTS `post-engagement` ( `uri-id` int unsigned NOT NULL COMMENT 'Id of the item-uri table entry that contains the item uri', `owner-id` int unsigned NOT NULL DEFAULT 0 COMMENT 'Item owner', `contact-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Person, organisation, news, community, relay', + `media-type` tinyint NOT NULL DEFAULT 0 COMMENT 'Type of media in a bit array (1 = image, 2 = video, 4 = audio', `created` datetime COMMENT '', `comments` mediumint unsigned COMMENT 'Number of comments', `activities` mediumint unsigned COMMENT 'Number of activities (like, dislike, ...)', diff --git a/doc/database/db_post-engagement.md b/doc/database/db_post-engagement.md index 8c4a2ae006..c261586b31 100644 --- a/doc/database/db_post-engagement.md +++ b/doc/database/db_post-engagement.md @@ -6,14 +6,15 @@ Engagement data per post Fields ------ -| 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 | | -| owner-id | Item owner | int unsigned | NO | | 0 | | -| contact-type | Person, organisation, news, community, relay | tinyint | NO | | 0 | | -| created | | datetime | YES | | NULL | | -| comments | Number of comments | mediumint unsigned | YES | | NULL | | -| activities | Number of activities (like, dislike, ...) | mediumint unsigned | YES | | NULL | | +| 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 | | +| owner-id | Item owner | int unsigned | 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 | | +| created | | datetime | YES | | NULL | | +| comments | Number of comments | mediumint unsigned | YES | | NULL | | +| activities | Number of activities (like, dislike, ...) | mediumint unsigned | YES | | NULL | | Indexes ------------ diff --git a/src/Model/Contact.php b/src/Model/Contact.php index dcb7ff99c4..944ff39cd5 100644 --- a/src/Model/Contact.php +++ b/src/Model/Contact.php @@ -533,6 +533,17 @@ class Contact return self::isSharing($cid, $uid, $strict); } + /** + * Checks if the provided public contact id has got followers on this system + * + * @param integer $cid + * @return boolean + */ + public static function hasFollowers(int $cid): bool + { + return DBA::exists('account-user-view', ["`pid` = ? AND `uid` != ? AND `rel` IN (?, ?)", $cid, 0, self::SHARING, self::FRIEND]); + } + /** * Get the basepath for a given contact link * diff --git a/src/Model/Post/Engagement.php b/src/Model/Post/Engagement.php index 81ba625023..3a54ee0f42 100644 --- a/src/Model/Post/Engagement.php +++ b/src/Model/Post/Engagement.php @@ -26,6 +26,7 @@ use Friendica\Core\Protocol; use Friendica\Database\Database; use Friendica\Database\DBA; use Friendica\DI; +use Friendica\Model\Contact; use Friendica\Model\Item; use Friendica\Model\Post; use Friendica\Model\Verb; @@ -49,11 +50,6 @@ class Engagement return; } - if ($item['gravity'] == Item::GRAVITY_PARENT) { - Logger::debug('Parent posts are not stored', ['uri-id' => $item['uri-id'], 'parent-uri-id' => $item['parent-uri-id']]); - 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; @@ -75,10 +71,23 @@ class Engagement return; } + $store = ($item['gravity'] != Item::GRAVITY_PARENT); + + if (!$store) { + $store = Contact::hasFollowers($parent['owner-id']); + } + + $mediatype = self::getMediaType($item['parent-uri-id']); + + if (!$store) { + $mediatype = !empty($mediatype); + } + $engagement = [ 'uri-id' => $item['parent-uri-id'], 'owner-id' => $parent['owner-id'], 'contact-type' => $parent['contact-contact-type'], + 'media-type' => $mediatype, 'created' => $parent['created'], 'comments' => DBA::count('post', ['parent-uri-id' => $item['parent-uri-id'], 'gravity' => Item::GRAVITY_COMMENT]), 'activities' => DBA::count('post', [ @@ -87,14 +96,30 @@ class Engagement Verb::getID(Activity::FOLLOW), Verb::getID(Activity::VIEW), Verb::getID(Activity::READ) ]) ]; - if (($engagement['comments'] == 0) && ($engagement['activities'] == 0)) { - Logger::debug('No comments nor activities. Engagement not stored', ['fields' => $engagement]); + if (!$store && ($engagement['comments'] == 0) && ($engagement['activities'] == 0)) { + Logger::debug('No media, follower, comments or activities. Engagement not stored', ['fields' => $engagement]); return; } $ret = DBA::insert('post-engagement', $engagement, Database::INSERT_UPDATE); Logger::debug('Engagement stored', ['fields' => $engagement, 'ret' => $ret]); } + private static function getMediaType(int $uri_id) : int + { + $media = Post\Media::getByURIId($uri_id); + $type = 0; + foreach ($media as $entry) { + if ($entry['type'] == Post\Media::IMAGE) { + $type = $type | 1; + } elseif ($entry['type'] == Post\Media::VIDEO) { + $type = $type | 2; + } elseif ($entry['type'] == Post\Media::AUDIO) { + $type = $type | 4; + } + } + return $type; + } + /** * Expire old engagement data * diff --git a/src/Module/Conversation/Channel.php b/src/Module/Conversation/Channel.php index 60488a2d4c..afc02764ba 100644 --- a/src/Module/Conversation/Channel.php +++ b/src/Module/Conversation/Channel.php @@ -45,6 +45,9 @@ class Channel extends BaseModule const WHATSHOT = 'whatshot'; const FORYOU = 'foryou'; const FOLLOWERS = 'followers'; + const IMAGE = 'image'; + const VIDEO = 'video'; + const AUDIO = 'audio'; /** * @} */ @@ -106,6 +109,33 @@ class Channel extends BaseModule 'accesskey' => 'h' ]; + $tabs[] = [ + 'label' => DI::l10n()->t('Images'), + 'url' => 'channel/' . self::IMAGE, + 'sel' => self::$content == self::IMAGE ? 'active' : '', + 'title' => DI::l10n()->t('Posts with images'), + 'id' => 'channel-image-tab', + 'accesskey' => 'i' + ]; + + $tabs[] = [ + 'label' => DI::l10n()->t('Videos'), + 'url' => 'channel/' . self::VIDEO, + 'sel' => self::$content == self::VIDEO ? 'active' : '', + 'title' => DI::l10n()->t('Posts with videos'), + 'id' => 'channel-video-tab', + 'accesskey' => 'v' + ]; + + $tabs[] = [ + 'label' => DI::l10n()->t('Audio'), + 'url' => 'channel/' . self::AUDIO, + 'sel' => self::$content == self::AUDIO ? 'active' : '', + 'title' => DI::l10n()->t('Posts with audio'), + 'id' => 'channel-audio-tab', + 'accesskey' => 'a' + ]; + $tab_tpl = Renderer::getMarkupTemplate('common_tabs.tpl'); $o .= Renderer::replaceMacros($tab_tpl, ['$tabs' => $tabs]); @@ -113,7 +143,7 @@ class Channel extends BaseModule DI::page()['aside'] .= Widget::accountTypes('channel/' . self::$content, self::$accountTypeString); - if ((self::$content != self::FOLLOWERS) && DI::config()->get('system', 'community_no_sharer')) { + if (!in_array(self::$content, [self::FOLLOWERS, self::FORYOU]) && DI::config()->get('system', 'community_no_sharer')) { $path = self::$content; if (!empty($this->parameters['accounttype'])) { $path .= '/' . $this->parameters['accounttype']; @@ -193,7 +223,7 @@ class Channel extends BaseModule self::$content = self::FORYOU; } - if (!in_array(self::$content, [self::WHATSHOT, self::FORYOU, self::FOLLOWERS])) { + if (!in_array(self::$content, [self::WHATSHOT, self::FORYOU, self::FOLLOWERS, self::IMAGE, self::VIDEO, self::AUDIO])) { throw new HTTPException\BadRequestException(DI::l10n()->t('Channel not available.')); } @@ -252,6 +282,12 @@ class Channel extends BaseModule DI::userSession()->getLocalUserId(), Contact::FRIEND, Contact::SHARING]; } elseif (self::$content == self::FOLLOWERS) { $condition = ["`owner-id` IN (SELECT `pid` FROM `account-user-view` WHERE `uid` = ? AND `rel` = ?)", DI::userSession()->getLocalUserId(), Contact::FOLLOWER]; + } elseif (self::$content == self::IMAGE) { + $condition = ["`media-type` & ?", 1]; + } elseif (self::$content == self::VIDEO) { + $condition = ["`media-type` & ?", 2]; + } elseif (self::$content == self::AUDIO) { + $condition = ["`media-type` & ?", 4]; } if ((self::$content != self::WHATSHOT) && !is_null(self::$accountType)) { @@ -309,7 +345,7 @@ class Channel extends BaseModule } $limit = DBA::count('post-engagement', ["`contact-type` != ? AND `comments` > ?", Contact::TYPE_COMMUNITY, 0]) / $divider; - $post = DBA::selectToArray('post-engagement', ['comments'], ["`contact-type` != ?", Contact::TYPE_COMMUNITY, 0], ['order' => ['comments' => true], 'limit' => [$limit, 1]]); + $post = DBA::selectToArray('post-engagement', ['comments'], ["`contact-type` != ?", Contact::TYPE_COMMUNITY], ['order' => ['comments' => true], 'limit' => [$limit, 1]]); $comments = $post[0]['comments'] ?? 0; if (empty($comments)) { return 0; @@ -328,7 +364,7 @@ class Channel extends BaseModule } $limit = DBA::count('post-engagement', ["`contact-type` != ? AND `activities` > ?", Contact::TYPE_COMMUNITY, 0]) / $divider; - $post = DBA::selectToArray('post-engagement', ['activities'], ["`contact-type` != ?", Contact::TYPE_COMMUNITY, 0], ['order' => ['activities' => true], 'limit' => [$limit, 1]]); + $post = DBA::selectToArray('post-engagement', ['activities'], ["`contact-type` != ?", Contact::TYPE_COMMUNITY], ['order' => ['activities' => true], 'limit' => [$limit, 1]]); $activities = $post[0]['activities'] ?? 0; if (empty($activities)) { return 0; diff --git a/static/dbstructure.config.php b/static/dbstructure.config.php index 3403a74692..2f654e3639 100644 --- a/static/dbstructure.config.php +++ b/static/dbstructure.config.php @@ -1329,6 +1329,7 @@ return [ "uri-id" => ["type" => "int unsigned", "not null" => "1", "primary" => "1", "foreign" => ["item-uri" => "id"], "comment" => "Id of the item-uri table entry that contains the item uri"], "owner-id" => ["type" => "int unsigned", "not null" => "1", "default" => "0", "foreign" => ["contact" => "id", "on delete" => "restrict"], "comment" => "Item owner"], "contact-type" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Person, organisation, news, community, relay"], + "media-type" => ["type" => "tinyint", "not null" => "1", "default" => "0", "comment" => "Type of media in a bit array (1 = image, 2 = video, 4 = audio"], "created" => ["type" => "datetime", "comment" => ""], "comments" => ["type" => "mediumint unsigned", "comment" => "Number of comments"], "activities" => ["type" => "mediumint unsigned", "comment" => "Number of activities (like, dislike, ...)"], diff --git a/view/lang/C/messages.po b/view/lang/C/messages.po index fbb0b5a282..85543ec02e 100644 --- a/view/lang/C/messages.po +++ b/view/lang/C/messages.po @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: 2023.09-dev\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2023-09-02 05:34+0000\n" +"POT-Creation-Date: 2023-09-02 15:51+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -793,7 +793,7 @@ msgid "All contacts" msgstr "" #: src/BaseModule.php:433 src/Content/Widget.php:239 src/Core/ACL.php:195 -#: src/Module/Contact.php:415 src/Module/Conversation/Channel.php:91 +#: src/Module/Contact.php:415 src/Module/Conversation/Channel.php:95 #: src/Module/PermissionTooltip.php:127 src/Module/PermissionTooltip.php:149 msgid "Followers" msgstr "" @@ -1669,31 +1669,31 @@ msgstr "" msgid "Follow Thread" msgstr "" -#: src/Content/Item.php:429 src/Model/Contact.php:1216 +#: src/Content/Item.php:429 src/Model/Contact.php:1221 msgid "View Status" msgstr "" -#: src/Content/Item.php:430 src/Content/Item.php:451 src/Model/Contact.php:1165 -#: src/Model/Contact.php:1208 src/Model/Contact.php:1217 +#: src/Content/Item.php:430 src/Content/Item.php:451 src/Model/Contact.php:1170 +#: src/Model/Contact.php:1213 src/Model/Contact.php:1222 #: src/Module/Directory.php:157 src/Module/Settings/Profile/Index.php:259 msgid "View Profile" msgstr "" -#: src/Content/Item.php:431 src/Model/Contact.php:1218 +#: src/Content/Item.php:431 src/Model/Contact.php:1223 msgid "View Photos" msgstr "" -#: src/Content/Item.php:432 src/Model/Contact.php:1209 -#: src/Model/Contact.php:1219 +#: src/Content/Item.php:432 src/Model/Contact.php:1214 +#: src/Model/Contact.php:1224 msgid "Network Posts" msgstr "" -#: src/Content/Item.php:433 src/Model/Contact.php:1210 -#: src/Model/Contact.php:1220 +#: src/Content/Item.php:433 src/Model/Contact.php:1215 +#: src/Model/Contact.php:1225 msgid "View Contact" msgstr "" -#: src/Content/Item.php:434 src/Model/Contact.php:1221 +#: src/Content/Item.php:434 src/Model/Contact.php:1226 msgid "Send PM" msgstr "" @@ -1728,7 +1728,7 @@ msgid "Languages" msgstr "" #: src/Content/Item.php:448 src/Content/Widget.php:80 -#: src/Model/Contact.php:1211 src/Model/Contact.php:1222 +#: src/Model/Contact.php:1216 src/Model/Contact.php:1227 #: src/Module/Contact/Follow.php:167 view/theme/vier/theme.php:195 msgid "Connect/Follow" msgstr "" @@ -2243,7 +2243,7 @@ msgstr "" msgid "Organisations" msgstr "" -#: src/Content/Widget.php:536 src/Model/Contact.php:1687 +#: src/Content/Widget.php:536 src/Model/Contact.php:1692 msgid "News" msgstr "" @@ -2324,8 +2324,8 @@ msgstr "" msgid "Network:" msgstr "" -#: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1212 -#: src/Model/Contact.php:1223 src/Model/Profile.php:463 +#: src/Content/Widget/VCard.php:118 src/Model/Contact.php:1217 +#: src/Model/Contact.php:1228 src/Model/Profile.php:463 #: src/Module/Contact/Profile.php:450 msgid "Unfollow" msgstr "" @@ -3078,82 +3078,82 @@ msgstr "" msgid "Edit circles" msgstr "" -#: src/Model/Contact.php:1229 src/Module/Moderation/Users/Pending.php:102 +#: src/Model/Contact.php:1234 src/Module/Moderation/Users/Pending.php:102 #: src/Module/Notifications/Introductions.php:132 #: src/Module/Notifications/Introductions.php:204 msgid "Approve" msgstr "" -#: src/Model/Contact.php:1683 +#: src/Model/Contact.php:1688 msgid "Organisation" msgstr "" -#: src/Model/Contact.php:1691 +#: src/Model/Contact.php:1696 msgid "Group" msgstr "" -#: src/Model/Contact.php:2994 +#: src/Model/Contact.php:2999 msgid "Disallowed profile URL." msgstr "" -#: src/Model/Contact.php:2999 src/Module/Friendica.php:101 +#: src/Model/Contact.php:3004 src/Module/Friendica.php:101 msgid "Blocked domain" msgstr "" -#: src/Model/Contact.php:3004 +#: src/Model/Contact.php:3009 msgid "Connect URL missing." msgstr "" -#: src/Model/Contact.php:3013 +#: src/Model/Contact.php:3018 msgid "" "The contact could not be added. Please check the relevant network " "credentials in your Settings -> Social Networks page." msgstr "" -#: src/Model/Contact.php:3031 +#: src/Model/Contact.php:3036 #, php-format msgid "Expected network %s does not match actual network %s" msgstr "" -#: src/Model/Contact.php:3048 +#: src/Model/Contact.php:3053 msgid "The profile address specified does not provide adequate information." msgstr "" -#: src/Model/Contact.php:3050 +#: src/Model/Contact.php:3055 msgid "No compatible communication protocols or feeds were discovered." msgstr "" -#: src/Model/Contact.php:3053 +#: src/Model/Contact.php:3058 msgid "An author or name was not found." msgstr "" -#: src/Model/Contact.php:3056 +#: src/Model/Contact.php:3061 msgid "No browser URL could be matched to this address." msgstr "" -#: src/Model/Contact.php:3059 +#: src/Model/Contact.php:3064 msgid "" "Unable to match @-style Identity Address with a known protocol or email " "contact." msgstr "" -#: src/Model/Contact.php:3060 +#: src/Model/Contact.php:3065 msgid "Use mailto: in front of address to force email check." msgstr "" -#: src/Model/Contact.php:3066 +#: src/Model/Contact.php:3071 msgid "" "The profile address specified belongs to a network which has been disabled " "on this site." msgstr "" -#: src/Model/Contact.php:3071 +#: src/Model/Contact.php:3076 msgid "" "Limited profile. This person will be unable to receive direct/personal " "notifications from you." msgstr "" -#: src/Model/Contact.php:3137 +#: src/Model/Contact.php:3142 msgid "Unable to retrieve contact information." msgstr "" @@ -6526,48 +6526,72 @@ msgstr "" msgid "Unable to unfollow this contact, please contact your administrator" msgstr "" -#: src/Module/Conversation/Channel.php:82 +#: src/Module/Conversation/Channel.php:86 msgid "For you" msgstr "" -#: src/Module/Conversation/Channel.php:85 +#: src/Module/Conversation/Channel.php:89 msgid "Posts from contacts you interact with and who interact with you" msgstr "" -#: src/Module/Conversation/Channel.php:94 +#: src/Module/Conversation/Channel.php:98 msgid "Posts from your followers that you don't follow" msgstr "" -#: src/Module/Conversation/Channel.php:100 +#: src/Module/Conversation/Channel.php:104 msgid "Whats Hot" msgstr "" -#: src/Module/Conversation/Channel.php:103 +#: src/Module/Conversation/Channel.php:107 msgid "Posts with a lot of interactions" msgstr "" -#: src/Module/Conversation/Channel.php:135 +#: src/Module/Conversation/Channel.php:113 +msgid "Images" +msgstr "" + +#: src/Module/Conversation/Channel.php:116 +msgid "Posts with images" +msgstr "" + +#: src/Module/Conversation/Channel.php:122 +msgid "Videos" +msgstr "" + +#: src/Module/Conversation/Channel.php:125 +msgid "Posts with videos" +msgstr "" + +#: src/Module/Conversation/Channel.php:131 +msgid "Audio" +msgstr "" + +#: src/Module/Conversation/Channel.php:134 +msgid "Posts with audio" +msgstr "" + +#: src/Module/Conversation/Channel.php:166 #: src/Module/Conversation/Community.php:134 msgid "Own Contacts" msgstr "" -#: src/Module/Conversation/Channel.php:139 +#: src/Module/Conversation/Channel.php:170 #: src/Module/Conversation/Community.php:138 msgid "Include" msgstr "" -#: src/Module/Conversation/Channel.php:140 +#: src/Module/Conversation/Channel.php:171 #: src/Module/Conversation/Community.php:139 msgid "Hide" msgstr "" -#: src/Module/Conversation/Channel.php:156 +#: src/Module/Conversation/Channel.php:187 #: src/Module/Conversation/Community.php:157 src/Module/Search/Index.php:152 #: src/Module/Search/Index.php:194 msgid "No results." msgstr "" -#: src/Module/Conversation/Channel.php:196 +#: src/Module/Conversation/Channel.php:227 msgid "Channel not available." msgstr "" -- 2.39.5