]> git.mxchange.org Git - friendica.git/commitdiff
Use reshare with Diaspora like with ActivityPub
authorMichael <heluecht@pirati.ca>
Tue, 13 Dec 2022 23:19:19 +0000 (23:19 +0000)
committerMichael <heluecht@pirati.ca>
Tue, 13 Dec 2022 23:19:19 +0000 (23:19 +0000)
database.sql
doc/database/db_post-user.md
src/Content/Conversation.php
src/Factory/Api/Mastodon/Status.php
src/Model/Post/UserNotification.php
src/Module/Api/Mastodon/Statuses/Reblog.php
src/Module/Api/Mastodon/Statuses/Unreblog.php
src/Module/Item/Activity.php
src/Navigation/Notifications/Factory/Notification.php
src/Protocol/Diaspora.php
static/dbstructure.config.php

index 49f282db0a315e5d76739e54ab871cefdcf8e7fb..7285d7fa1e278c1a2c79d784121a2ec89f96626a 100644 (file)
@@ -1,6 +1,6 @@
 -- ------------------------------------------
 -- Friendica 2022.12-rc (Giant Rhubarb)
--- DB_UPDATE_VERSION 1501
+-- DB_UPDATE_VERSION 1502
 -- ------------------------------------------
 
 
@@ -1439,7 +1439,7 @@ CREATE TABLE IF NOT EXISTS `post-user` (
        `event-id` int unsigned COMMENT 'Used to link to the event.id',
        `unseen` boolean NOT NULL DEFAULT '1' COMMENT 'post has not been seen',
        `hidden` boolean NOT NULL DEFAULT '0' COMMENT 'Marker to hide the post from the user',
-       `notification-type` tinyint unsigned NOT NULL DEFAULT 0 COMMENT '',
+       `notification-type` smallint unsigned NOT NULL DEFAULT 0 COMMENT '',
        `wall` boolean NOT NULL DEFAULT '0' COMMENT 'This item was posted to the wall of uid',
        `origin` boolean NOT NULL DEFAULT '0' COMMENT 'item originated at this site',
        `psid` int unsigned COMMENT 'ID of the permission set of this post',
index ce213941dac071e890e6c6b09a3d0eeae81fe6e6..2fe91d144b4a74436a6729c98e3b63332c325c65 100644 (file)
@@ -34,7 +34,7 @@ Fields
 | event-id          | Used to link to the event.id                                                      | int unsigned       | YES  |     | NULL                |                |
 | unseen            | post has not been seen                                                            | boolean            | NO   |     | 1                   |                |
 | hidden            | Marker to hide the post from the user                                             | boolean            | NO   |     | 0                   |                |
-| notification-type |                                                                                   | tinyint unsigned   | NO   |     | 0                   |                |
+| notification-type |                                                                                   | smallint unsigned  | NO   |     | 0                   |                |
 | wall              | This item was posted to the wall of uid                                           | boolean            | NO   |     | 0                   |                |
 | origin            | item originated at this site                                                      | boolean            | NO   |     | 0                   |                |
 | psid              | ID of the permission set of this post                                             | int unsigned       | YES  |     | NULL                |                |
index 6d19eb16356ce450d22f7ee4714a167285b948c8..f8885b5b07853ebba3f45f29895530f4f340becc 100644 (file)
@@ -985,7 +985,8 @@ class Conversation
 
                $thread_items = Post::selectForUser($uid, array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), $condition, $params);
 
-               $items = [];
+               $items       = [];
+               $quoteuriids = [];
 
                while ($row = Post::fetch($thread_items)) {
                        if (!empty($items[$row['uri-id']]) && ($row['uid'] == 0)) {
@@ -1005,11 +1006,37 @@ class Conversation
                                }
                        }
 
+                       if (in_array($row['gravity'], [ItemModel::GRAVITY_PARENT, ItemModel::GRAVITY_COMMENT])) {
+                               $quoteuriids[$row['uri-id']] = [
+                                       'uri-id'        => $row['uri-id'],
+                                       'uri'           => $row['uri'],
+                                       'parent-uri-id' => $row['parent-uri-id'],
+                                       'parent-uri'    => $row['parent-uri'],
+                               ];
+                       }
+
                        $items[$row['uri-id']] = $this->addRowInformation($row, $activities[$row['uri-id']] ?? [], $thr_parent[$row['thr-parent-id']] ?? []);
                }
 
                DBA::close($thread_items);
 
+               $quotes = Post::select(array_merge(ItemModel::DISPLAY_FIELDLIST, ['featured', 'contact-uid', 'gravity', 'post-type', 'post-reason']), ['quote-uri-id' => array_column($quoteuriids, 'uri-id'), 'uid' => 0]);
+               while ($quote = Post::fetch($quotes)) {
+                       $row = $quote;
+
+                       $row['uid']           = $uid;
+                       $row['verb']          = $row['body'] = $row['raw-body'] = Activity::ANNOUNCE;
+                       $row['gravity']       = ItemModel::GRAVITY_ACTIVITY;
+                       $row['object-type']   = Activity\ObjectType::NOTE;
+                       $row['parent-uri']    = $quoteuriids[$quote['quote-uri-id']]['parent-uri'];
+                       $row['parent-uri-id'] = $quoteuriids[$quote['quote-uri-id']]['parent-uri-id'];
+                       $row['thr-parent']    = $quoteuriids[$quote['quote-uri-id']]['uri'];
+                       $row['thr-parent-id'] = $quoteuriids[$quote['quote-uri-id']]['uri-id'];
+
+                       $items[$row['uri-id']] = $this->addRowInformation($row, [], []);
+               }
+               DBA::close($quotes);
+
                $items = $this->convSort($items, $order);
 
                $this->profiler->stopRecording();
index 18701bb661f36a481cad2cc3b758ad4617eae3d8..698c127f722209bbe2f9fcd9d4fbd398319bd696 100644 (file)
@@ -115,13 +115,17 @@ class Status extends BaseFactory
                        'gravity'       => Item::GRAVITY_ACTIVITY,
                        'vid'           => Verb::getID(Activity::ANNOUNCE),
                        'deleted'       => false
-               ], []);
+               ]) + Post::countPosts([
+                       'quote-uri-id' => $uriId,
+                       'deleted'       => false
+               ]);
+
                $count_like = Post::countPosts([
                        'thr-parent-id' => $uriId,
                        'gravity'       => Item::GRAVITY_ACTIVITY,
                        'vid'           => Verb::getID(Activity::LIKE),
                        'deleted'       => false
-               ], []);
+               ]);
 
                $counts = new \Friendica\Object\Api\Mastodon\Status\Counts(
                        Post::countPosts(['thr-parent-id' => $uriId, 'gravity' => Item::GRAVITY_COMMENT, 'deleted' => false], []),
@@ -144,6 +148,11 @@ class Status extends BaseFactory
                        'gravity'       => Item::GRAVITY_ACTIVITY,
                        'vid'           => Verb::getID(Activity::ANNOUNCE),
                        'deleted'       => false
+               ]) || Post::exists([
+                       'quote-uri-id' => $uriId,
+                       'uid'           => $uid,
+                       'origin'        => true,
+                       'deleted'       => false
                ]);
                $userAttributes = new \Friendica\Object\Api\Mastodon\Status\UserAttributes(
                        $origin_like,
index d872d5c41cbf95395aeeb0eb2281d22b7d93634f..44a7dd9000a9794e9878fe6452352cb6fd5edfb1 100644 (file)
@@ -27,7 +27,6 @@ use Friendica\Core\Hook;
 use Friendica\Core\Logger;
 use Friendica\Database\Database;
 use Friendica\Database\DBA;
-use Friendica\Database\DBStructure;
 use Friendica\DI;
 use Friendica\Model\Contact;
 use Friendica\Model\Item;
@@ -52,6 +51,7 @@ class UserNotification
        const TYPE_DIRECT_THREAD_COMMENT  = 64;
        const TYPE_SHARED                 = 128;
        const TYPE_FOLLOW                 = 256;
+       const TYPE_QUOTED                 = 512;
 
        /**
         * Insert a new user notification entry
@@ -273,6 +273,14 @@ class UserNotification
                        }
                }
 
+               if (($item['verb'] != Activity::ANNOUNCE) && self::checkQuoted($item, $contacts)) {
+                       $notification_type = $notification_type | self::TYPE_QUOTED;
+                       if (!$notified) {
+                               self::insertNotificationByItem(self::TYPE_QUOTED, $uid, $item);
+                               $notified = true;
+                       }
+               }
+
                if (($item['verb'] != Activity::ANNOUNCE) && self::checkFollowParticipation($item, $contacts)) {
                        $notification_type = $notification_type | self::TYPE_FOLLOW;
                        if (!$notified) {
@@ -581,4 +589,23 @@ class UserNotification
                $condition = ['parent' => $item['parent'], 'author-id' => $contacts, 'deleted' => false, 'gravity' => Item::GRAVITY_ACTIVITY];
                return Post::exists($condition);
        }
+
+       /**
+        * Check for a quoted post of a post of the given user
+        *
+        * @param array $item
+        * @param array $contacts Array of contact IDs
+        * @return bool The item is a quoted post of a user's post or comment
+        * @throws Exception
+        */
+       private static function checkQuoted(array $item, array $contacts): bool
+       {
+               if (empty($item['quote-uri-id'])) {
+                       return false;
+               }
+               $condition = ['uri-id' => $item['quote-uri-id'], 'uid' => $item['uid'], 'author-id' => $contacts, 'deleted' => false, 'gravity' => [item::GRAVITY_PARENT, Item::GRAVITY_COMMENT]];
+               return Post::exists($condition);
+       }
+
+       
 }
index 65b641ab89eca1c570fa89a6f4b34b25ec31aaaa..bf4a73946676f12de2c655c600d38be4c53d376f 100644 (file)
@@ -29,6 +29,7 @@ use Friendica\DI;
 use Friendica\Model\Item;
 use Friendica\Model\Post;
 use Friendica\Module\BaseApi;
+use Friendica\Protocol\Diaspora;
 
 /**
  * @see https://docs.joinmastodon.org/methods/statuses/
@@ -49,12 +50,14 @@ class Reblog extends BaseApi
                        DI::mstdnError()->RecordNotFound();
                }
 
-               if (!in_array($item['network'], [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::TWITTER])) {
+               if ($item['network'] == Protocol::DIASPORA) {
+                       Diaspora::performReshare($this->parameters['id'], $uid);
+               } elseif (!in_array($item['network'], [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::TWITTER])) {
                        DI::mstdnError()->UnprocessableEntity(DI::l10n()->t("Posts from %s can't be shared", ContactSelector::networkToName($item['network'])));
+               } else {
+                       Item::performActivity($item['id'], 'announce', $uid);
                }
 
-               Item::performActivity($item['id'], 'announce', $uid);
-
                System::jsonExit(DI::mstdnStatus()->createFromUriId($this->parameters['id'], $uid)->toArray());
        }
 }
index a6741c6de2ad3a13ffe39ad81d44583048554b5f..faacefe38d00454a61ad028ba567f7f760f3a700 100644 (file)
@@ -49,12 +49,21 @@ class Unreblog extends BaseApi
                        DI::mstdnError()->RecordNotFound();
                }
 
-               if (!in_array($item['network'], [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::TWITTER])) {
+               if ($item['network'] == Protocol::DIASPORA) {
+                       $item = Post::selectFirstForUser($uid, ['id'], ['quote-uri-id' => $this->parameters['id'], 'origin' => true, 'uid' => $uid]);
+                       if (empty($item['id'])) {
+                               DI::mstdnError()->RecordNotFound();
+                       }
+       
+                       if (!Item::markForDeletionById($item['id'])) {
+                               DI::mstdnError()->RecordNotFound();
+                       }
+               } elseif (!in_array($item['network'], [Protocol::DFRN, Protocol::ACTIVITYPUB, Protocol::TWITTER])) {
                        DI::mstdnError()->UnprocessableEntity(DI::l10n()->t("Posts from %s can't be unshared", ContactSelector::networkToName($item['network'])));
+               } else {
+                       Item::performActivity($item['id'], 'unannounce', $uid);
                }
 
-               Item::performActivity($item['id'], 'unannounce', $uid);
-
                System::jsonExit(DI::mstdnStatus()->createFromUriId($this->parameters['id'], $uid)->toArray());
        }
 }
index 3fa6d38fc90aceedb84b168efbc5d40ad261e3ed..c52882efb8d0b56d68eb4bafabb78a94a76e4a05 100644 (file)
@@ -46,17 +46,26 @@ class Activity extends BaseModule
                        throw new HTTPException\BadRequestException();
                }
 
-               $verb = $this->parameters['verb'];
-               $itemId =  $this->parameters['id'];
+               $verb    = $this->parameters['verb'];
+               $itemId  = $this->parameters['id'];
+               $handled = false;
 
                if (in_array($verb, ['announce', 'unannounce'])) {
                        $item = Post::selectFirst(['network', 'uri-id'], ['id' => $itemId, 'uid' => [DI::userSession()->getLocalUserId(), 0]]);
                        if ($item['network'] == Protocol::DIASPORA) {
-                               Diaspora::performReshare($item['uri-id'], DI::userSession()->getLocalUserId());
+                               $quote = Post::selectFirst(['id'], ['quote-uri-id' => $item['uri-id'], 'origin' => true, 'uid' => DI::userSession()->getLocalUserId()]);
+                               if (!empty($quote['id'])) {
+                                       if (!Item::markForDeletionById($quote['id'])) {
+                                               throw new HTTPException\BadRequestException();
+                                       }
+                               } else {
+                                       Diaspora::performReshare($item['uri-id'], DI::userSession()->getLocalUserId());
+                               }
+                               $handled = true;
                        }
                }
 
-               if (!Item::performActivity($itemId, $verb, DI::userSession()->getLocalUserId())) {
+               if (!$handled && !Item::performActivity($itemId, $verb, DI::userSession()->getLocalUserId())) {
                        throw new HTTPException\BadRequestException();
                }
 
index 7f6988b3bf927e028a1fd0fb143e7981c0483807..86d462e0b260a99a3b4dc6bc5c1f30a4927e39aa 100644 (file)
@@ -311,7 +311,11 @@ class Notification extends BaseFactory implements ICanCreateFromTableRow
                                                                $msg = $l10n->t('%1$s shared a post');
                                                        }
                                                        break;
-                                       }
+
+                                               case Post\UserNotification::TYPE_QUOTED:
+                                                       $msg = $l10n->t('%1$s shared your post %2$s');
+                                                       break;
+                                               }
                                        break;
                        }
                }
index fe5b27d334f313d0b1817ac1bafb46e09b925113..8e2dc56d9e60db1f1a418f8c135f6be3c0e63f5d 100644 (file)
@@ -2285,65 +2285,6 @@ class Diaspora
                return true;
        }
 
-       /**
-        * Stores a reshare activity
-        *
-        * @param array        $item              Array of reshare post
-        * @param integer      $parent_message_id Id of the parent post
-        * @param string       $guid              GUID string of reshare action
-        * @param WebFingerUri $author            Author handle
-        * @return false|void
-        * @throws InternalServerErrorException
-        * @throws \ImagickException
-        */
-       private static function addReshareActivity(array $item, int $parent_message_id, string $guid, WebFingerUri $author)
-       {
-               $parent = Post::selectFirst(['uri', 'guid'], ['id' => $parent_message_id]);
-
-               $datarray = [];
-
-               $datarray['uid'] = $item['uid'];
-               $datarray['contact-id'] = $item['contact-id'];
-               $datarray['network'] = $item['network'];
-
-               $datarray['author-link'] = $item['author-link'];
-               $datarray['author-id'] = $item['author-id'];
-
-               $datarray['owner-link'] = $datarray['author-link'];
-               $datarray['owner-id'] = $datarray['author-id'];
-
-               $datarray['guid'] = $parent['guid'] . '-' . $guid;
-               $datarray['uri'] = self::getUriFromGuid($datarray['guid'], $author);
-               $datarray['thr-parent'] = $parent['uri'];
-
-               $datarray['verb'] = $datarray['body'] = Activity::ANNOUNCE;
-               $datarray['gravity'] = Item::GRAVITY_ACTIVITY;
-               $datarray['object-type'] = Activity\ObjectType::NOTE;
-
-               $datarray['protocol'] = $item['protocol'];
-               $datarray['source'] = $item['source'];
-               $datarray['direction'] = $item['direction'];
-               $datarray['post-reason'] = $item['post-reason'];
-
-               $datarray['plink'] = self::plink($author, $datarray['guid']);
-               $datarray['private'] = $item['private'];
-               $datarray['changed'] = $datarray['created'] = $datarray['edited'] = $item['created'];
-
-               if (Item::isTooOld($datarray)) {
-                       Logger::info('Reshare activity is too old', ['created' => $datarray['created'], 'uid' => $datarray['uid'], 'guid' => $datarray['guid']]);
-                       return false;
-               }
-
-               $message_id = Item::insert($datarray);
-
-               if ($message_id) {
-                       Logger::info('Stored reshare activity.', ['guid' => $guid, 'id' => $message_id]);
-                       if ($datarray['uid'] == 0) {
-                               Item::distribute($message_id);
-                       }
-               }
-       }
-
        /**
         * Processes a reshare message
         *
@@ -2436,11 +2377,6 @@ class Diaspora
 
                self::sendParticipation($contact, $datarray);
 
-               $root_message_id = self::messageExists($importer['uid'], $root_guid);
-               if ($root_message_id) {
-                       self::addReshareActivity($datarray, $root_message_id, $guid, $author);
-               }
-
                if ($message_id) {
                        Logger::info('Stored reshare ' . $datarray['guid'] . ' with message id ' . $message_id);
                        if ($datarray['uid'] == 0) {
index d9ff07178bd05b4f393124583f22bdaae5a3741c..4a340d1f7b687deeca677c80f41f145a05ae9fb0 100644 (file)
@@ -55,7 +55,7 @@
 use Friendica\Database\DBA;
 
 if (!defined('DB_UPDATE_VERSION')) {
-       define('DB_UPDATE_VERSION', 1501);
+       define('DB_UPDATE_VERSION', 1502);
 }
 
 return [
@@ -1458,7 +1458,7 @@ return [
                        "event-id" => ["type" => "int unsigned", "foreign" => ["event" => "id"], "comment" => "Used to link to the event.id"],
                        "unseen" => ["type" => "boolean", "not null" => "1", "default" => "1", "comment" => "post has not been seen"],
                        "hidden" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "Marker to hide the post from the user"],
-                       "notification-type" => ["type" => "tinyint unsigned", "not null" => "1", "default" => "0", "comment" => ""],
+                       "notification-type" => ["type" => "smallint unsigned", "not null" => "1", "default" => "0", "comment" => ""],
                        "wall" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "This item was posted to the wall of uid"],
                        "origin" => ["type" => "boolean", "not null" => "1", "default" => "0", "comment" => "item originated at this site"],
                        "psid" => ["type" => "int unsigned", "foreign" => ["permissionset" => "id", "on delete" => "restrict"], "comment" => "ID of the permission set of this post"],