[PATCH 3/4] WIP: support show --duplicate for structured output

Subject: [PATCH 3/4] WIP: support show --duplicate for structured output

Date: Sun, 12 Jun 2022 16:04:58 -0300

To: notmuch@notmuchmail.org

Cc:

From: David Bremner


---
 mime-node.c       | 32 +++++++++++++++++++++++---------
 notmuch-client.h  |  4 +++-
 notmuch-reply.c   |  2 +-
 notmuch-show.c    |  2 +-
 test/T520-show.sh | 24 ++++++++++++++++++++++++
 5 files changed, 52 insertions(+), 12 deletions(-)

diff --git a/mime-node.c b/mime-node.c
index d29c4e48..890c8a0d 100644
--- a/mime-node.c
+++ b/mime-node.c
@@ -78,13 +78,14 @@ mime_node_get_message_crypto_status (mime_node_t *node)
 
 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
+		int duplicate,
 		_notmuch_crypto_t *crypto, mime_node_t **root_out)
 {
     const char *filename = notmuch_message_get_filename (message);
     mime_node_context_t *mctx;
     mime_node_t *root;
     notmuch_status_t status;
-    int fd;
+    int fd = -1;
 
     root = talloc_zero (ctx, mime_node_t);
     if (root == NULL) {
@@ -103,20 +104,33 @@ mime_node_open (const void *ctx, notmuch_message_t *message,
     talloc_set_destructor (mctx, _mime_node_context_free);
 
     /* Fast path */
-    fd = open (filename, O_RDONLY);
+    if (duplicate <= 0)
+	fd = open (filename, O_RDONLY);
     if (fd == -1) {
-	/* Slow path - for some reason the first file in the list is
-	 * not available anymore. This is clearly a problem in the
+	/* Slow path - Either we are trying to open a specific file, or
+	 * for some reason the first file in the list is
+	 * not available anymore. The latter is clearly a problem in the
 	 * database, but we are not going to let this problem be a
 	 * show stopper */
 	notmuch_filenames_t *filenames;
+	int i=1;
+
 	for (filenames = notmuch_message_get_filenames (message);
 	     notmuch_filenames_valid (filenames);
-	     notmuch_filenames_move_to_next (filenames)) {
-	    filename = notmuch_filenames_get (filenames);
-	    fd = open (filename, O_RDONLY);
-	    if (fd != -1)
-		break;
+	     notmuch_filenames_move_to_next (filenames), i++) {
+	    if (i>= duplicate) {
+		filename = notmuch_filenames_get (filenames);
+		fd = open (filename, O_RDONLY);
+		if (fd != -1) {
+		    break;
+		} else {
+		    if (duplicate > 0) {
+			fprintf (stderr, "Error opening %s: %s\n", filename, strerror (errno));
+			status = NOTMUCH_STATUS_FILE_ERROR;
+			goto DONE;
+		    }
+		}
+	    }
 	}
 
 	talloc_free (filenames);
diff --git a/notmuch-client.h b/notmuch-client.h
index f8f987e7..faea52b7 100644
--- a/notmuch-client.h
+++ b/notmuch-client.h
@@ -389,7 +389,8 @@ struct mime_node {
 };
 
 /* Construct a new MIME node pointing to the root message part of
- * message. If crypto->verify is true, signed child parts will be
+ * message. Use the duplicate-th filename if that parameter is
+ * positive. If crypto->verify is true, signed child parts will be
  * verified. If crypto->decrypt is NOTMUCH_DECRYPT_TRUE, encrypted
  * child parts will be decrypted using either stored session keys or
  * asymmetric crypto.  If crypto->decrypt is NOTMUCH_DECRYPT_AUTO,
@@ -407,6 +408,7 @@ struct mime_node {
  */
 notmuch_status_t
 mime_node_open (const void *ctx, notmuch_message_t *message,
+		int duplicate,
 		_notmuch_crypto_t *crypto, mime_node_t **node_out);
 
 /* Return a new MIME node for the requested child part of parent.
diff --git a/notmuch-reply.c b/notmuch-reply.c
index 9fca22db..ee50bb22 100644
--- a/notmuch-reply.c
+++ b/notmuch-reply.c
@@ -663,7 +663,7 @@ do_reply (notmuch_database_t *notmuch,
 	 notmuch_messages_move_to_next (messages)) {
 	message = notmuch_messages_get (messages);
 
-	if (mime_node_open (notmuch, message, &params->crypto, &node))
+	if (mime_node_open (notmuch, message, 0, &params->crypto, &node))
 	    return 1;
 
 	reply = create_reply_message (notmuch, message,
diff --git a/notmuch-show.c b/notmuch-show.c
index 7b57aab3..ccaf9fa0 100644
--- a/notmuch-show.c
+++ b/notmuch-show.c
@@ -1018,7 +1018,7 @@ show_message (void *ctx,
 	session_key_count_error = notmuch_message_count_properties (message, "session-key",
 								    &session_keys);
 
-    status = mime_node_open (local, message, &(params->crypto), &root);
+    status = mime_node_open (local, message, params->duplicate, &(params->crypto), &root);
     if (status)
 	goto DONE;
     part = mime_node_seek_dfs (root, (params->part < 0 ? 0 : params->part));
diff --git a/test/T520-show.sh b/test/T520-show.sh
index 12bde6c7..a19b4d57 100755
--- a/test/T520-show.sh
+++ b/test/T520-show.sh
@@ -45,4 +45,28 @@ if [ $NOTMUCH_HAVE_SFSEXP -eq 1 ]; then
 
 fi
 
+add_email_corpus duplicate
+
+ID1=debian/2.6.1.dfsg-4-1-g87ea161@87ea161e851dfb1ea324af00e4ecfccc18875e15
+test_begin_subtest "format json, subject, --duplicate=1"
+output=$(notmuch show --format=json --duplicate=1 id:${ID1})
+file=$(notmuch search --output=files id:${ID1} | head -n 1)
+subject=$(sed -n 's/^Subject: \(.*\)$/\1/p' < $file)
+test_json_nodes <<<"$output" "subject:['headers']['Subject']=\"$subject\""
+
+test_begin_subtest "format json, subject, --duplicate=2"
+output=$(notmuch show --format=json --duplicate=2 id:${ID1})
+file=$(notmuch search --output=files id:${ID1} | tail -n 1)
+subject=$(sed -n 's/^Subject: \(.*\)$/\1/p' < $file)
+test_json_nodes <<<"$output" "subject:['headers']['Subject']=\"$subject\""
+
+ID2=87r2geywh9.fsf@tethera.net
+for dup in {1..2}; do
+    test_begin_subtest "format json, body, --duplicate=${dup}"
+    output=$(notmuch show --format=json --duplicate=${dup} id:${ID2} | \
+	     python $NOTMUCH_SRCDIR/test/json_check_nodes.py "body:['body'][0]['content']" | \
+	     grep '^# body')
+    test_expect_equal "$output" "# body ${dup}"
+done
+
 test_done
-- 
2.35.2

_______________________________________________
notmuch mailing list -- notmuch@notmuchmail.org
To unsubscribe send an email to notmuch-leave@notmuchmail.org

Thread: