From 297118f90296b9cf147efc81dbe849f2b7e75cf8 Mon Sep 17 00:00:00 2001
From: Michael <heluecht@pirati.ca>
Date: Sat, 12 Dec 2020 16:45:23 +0000
Subject: [PATCH] Archive/Unarchive at ActivityPub delivery

---
 src/Model/Contact.php                    |  4 ++--
 src/Protocol/ActivityPub/Transmitter.php | 20 +++++++++++++-------
 src/Worker/APDelivery.php                | 17 ++++++++++++++++-
 src/Worker/Notifier.php                  |  8 ++++----
 4 files changed, 35 insertions(+), 14 deletions(-)

diff --git a/src/Model/Contact.php b/src/Model/Contact.php
index b645893776..df21796c18 100644
--- a/src/Model/Contact.php
+++ b/src/Model/Contact.php
@@ -809,7 +809,7 @@ class Contact
 			Logger::info('Empty contact', ['contact' => $contact, 'callstack' => System::callstack(20)]);
 		}
 
-		Logger::info('Contact is marked for archival', ['id' => $contact['id']]);
+		Logger::info('Contact is marked for archival', ['id' => $contact['id'], 'term-date' => $contact['term-date']]);
 
 		// Contact already archived or "self" contact? => nothing to do
 		if ($contact['archive'] || $contact['self']) {
@@ -867,7 +867,7 @@ class Contact
 			return;
 		}
 
-		Logger::info('Contact is marked as vital again', ['id' => $contact['id']]);
+		Logger::info('Contact is marked as vital again', ['id' => $contact['id'], 'term-date' => $contact['term-date']]);
 
 		if (!isset($contact['url']) && !empty($contact['id'])) {
 			$fields = ['id', 'url', 'batch'];
diff --git a/src/Protocol/ActivityPub/Transmitter.php b/src/Protocol/ActivityPub/Transmitter.php
index ed1ac43c76..cf0b0170d7 100644
--- a/src/Protocol/ActivityPub/Transmitter.php
+++ b/src/Protocol/ActivityPub/Transmitter.php
@@ -74,7 +74,7 @@ class Transmitter
 			["`type` = ? AND `url` IN (SELECT `url` FROM `contact` WHERE `uid` = ? AND `rel` IN (?, ?))",
 				'Application', 0, Contact::FOLLOWER, Contact::FRIEND]);
 		while ($contact = DBA::fetch($contacts)) {
-			$inboxes[] = $contact['inbox'];
+			$inboxes[$contact['inbox']] = $contact['inbox'];
 		}
 		DBA::close($contacts);
 
@@ -89,15 +89,19 @@ class Transmitter
 	 */
 	public static function addRelayServerInboxesForItem(int $item_id, array $inboxes = [])
 	{
+		$item = Item::selectFirst(['uid'], ['id' => $item_id]);
+		if (empty($item)) {
+			return $inboxes;
+		}
+
 		$relays = Relay::getList($item_id, [], [Protocol::ACTIVITYPUB]);
 		if (empty($relays)) {
 			return $inboxes;
 		}
 
 		foreach ($relays as $relay) {
-			if (!in_array($relay['batch'], $inboxes)) {
-				$inboxes[] = $relay['batch'];
-			}
+			$contact = Contact::getByURLForUser($relay['url'], $item['uid'], false, ['id']);
+			$inboxes[$relay['batch']][] = $contact['id'] ?? 0;
 		}
 		return $inboxes;
 	}
@@ -728,7 +732,7 @@ class Transmitter
 			$condition['rel'] = [Contact::FOLLOWER, Contact::FRIEND];
 		}
 
-		$contacts = DBA::select('contact', ['url', 'network', 'protocol'], $condition);
+		$contacts = DBA::select('contact', ['id', 'url', 'network', 'protocol'], $condition);
 		while ($contact = DBA::fetch($contacts)) {
 			if (Contact::isLocal($contact['url'])) {
 				continue;
@@ -754,7 +758,7 @@ class Transmitter
 					$target = $profile['sharedinbox'];
 				}
 				if (!self::archivedInbox($target)) {
-					$inboxes[$target] = $target;
+					$inboxes[$target][] = $contact['id'];
 				}
 			}
 		}
@@ -817,13 +821,15 @@ class Transmitter
 
 					$profile = APContact::getByURL($receiver, false);
 					if (!empty($profile)) {
+						$contact = Contact::getByURLForUser($receiver, $uid, false, ['id']);
+
 						if (empty($profile['sharedinbox']) || $personal || $blindcopy) {
 							$target = $profile['inbox'];
 						} else {
 							$target = $profile['sharedinbox'];
 						}
 						if (!self::archivedInbox($target)) {
-							$inboxes[$target] = $target;
+							$inboxes[$target][] = $contact['id'] ?? 0;
 						}
 					}
 				}
diff --git a/src/Worker/APDelivery.php b/src/Worker/APDelivery.php
index a25977372a..7173475bef 100644
--- a/src/Worker/APDelivery.php
+++ b/src/Worker/APDelivery.php
@@ -23,6 +23,7 @@ namespace Friendica\Worker;
 
 use Friendica\Core\Logger;
 use Friendica\Core\Worker;
+use Friendica\Model\Contact;
 use Friendica\Model\Item;
 use Friendica\Model\Post;
 use Friendica\Protocol\ActivityPub;
@@ -37,10 +38,11 @@ class APDelivery
 	 * @param integer $target_id
 	 * @param string  $inbox
 	 * @param integer $uid
+	 * @param array   $receivers
 	 * @throws \Friendica\Network\HTTPException\InternalServerErrorException
 	 * @throws \ImagickException
 	 */
-	public static function execute($cmd, $target_id, $inbox, $uid)
+	public static function execute($cmd, $target_id, $inbox, $uid, $receivers = [])
 	{
 		if (ActivityPub\Transmitter::archivedInbox($inbox)) {
 			Logger::info('Inbox is archived', ['cmd' => $cmd, 'inbox' => $inbox, 'id' => $target_id, 'uid' => $uid]);
@@ -81,6 +83,19 @@ class APDelivery
 		$item = Item::selectFirst(['uri-id'], ['id' => $target_id]);
 		$uriid = $item['uri-id'] ?? 0;
 
+		foreach ($receivers as $receiver) {
+			$contact = Contact::getById($receiver);
+			if (empty($contact)) {
+				continue;
+			}
+
+			if ($success) {
+				Contact::unmarkForArchival($contact);
+			} else {
+				Contact::markForArchival($contact);
+			}
+		}
+
 		if (!$success && !Worker::defer() && in_array($cmd, [Delivery::POST])) {
 			Post\DeliveryData::incrementQueueFailed($uriid);
 		} elseif ($success && in_array($cmd, [Delivery::POST])) {
diff --git a/src/Worker/Notifier.php b/src/Worker/Notifier.php
index 3be00359e5..02992898ca 100644
--- a/src/Worker/Notifier.php
+++ b/src/Worker/Notifier.php
@@ -824,20 +824,20 @@ class Notifier
 
 		$delivery_queue_count = 0;
 
-		foreach ($inboxes as $inbox) {
+		foreach ($inboxes as $inbox => $receivers) {
 			Logger::info('Delivery via ActivityPub', ['cmd' => $cmd, 'id' => $target_item['id'], 'inbox' => $inbox]);
 
 			if (Worker::add(['priority' => $priority, 'created' => $created, 'dont_fork' => true],
-					'APDelivery', $cmd, $target_item['id'], $inbox, $uid)) {
+					'APDelivery', $cmd, $target_item['id'], $inbox, $uid, $receivers)) {
 				$delivery_queue_count++;
 			}
 		}
 
 		// We deliver posts to relay servers slightly delayed to priorize the direct delivery
-		foreach ($relay_inboxes as $inbox) {
+		foreach ($relay_inboxes as $inbox => $receivers) {
 			Logger::info('Delivery to relay servers via ActivityPub', ['cmd' => $cmd, 'id' => $target_item['id'], 'inbox' => $inbox]);
 
-			if (Worker::add(['priority' => $priority, 'dont_fork' => true], 'APDelivery', $cmd, $target_item['id'], $inbox, $uid)) {
+			if (Worker::add(['priority' => $priority, 'dont_fork' => true], 'APDelivery', $cmd, $target_item['id'], $inbox, $uid, $receivers)) {
 				$delivery_queue_count++;
 			}
 		}