add jmap_mailbox_get_mails dav-2 tip

Sat, 11 Jul 2026 20:57:23 +0200

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Sat, 11 Jul 2026 20:57:23 +0200
branch
dav-2
changeset 928
57167625bfdd
parent 927
0bcf3d69b37a

add jmap_mailbox_get_mails

jmap/jmmail.c file | annotate | diff | comparison | revisions
libidav/jmap_mail.c file | annotate | diff | comparison | revisions
libidav/jmap_mail.h file | annotate | diff | comparison | revisions
libidav/jmap_methods.c file | annotate | diff | comparison | revisions
libidav/jmap_methods.h file | annotate | diff | comparison | revisions
--- a/jmap/jmmail.c	Fri Jul 10 17:56:21 2026 +0200
+++ b/jmap/jmmail.c	Sat Jul 11 20:57:23 2026 +0200
@@ -105,13 +105,26 @@
     const char *password = argv[3];
     
     JMAPSession *sn = jmap_session_new_with_user(session_url, user, password);
-    curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L);
-    curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr);
+    //curl_easy_setopt(sn->handle, CURLOPT_VERBOSE, 1L);
+    //curl_easy_setopt(sn->handle, CURLOPT_STDERR, stderr);
     
     CxList *mailboxes = jmap_mailbox_get_list(sn);
     CxIterator i = cxListIterator(mailboxes);
+    JMAPMailBox *inbox = NULL;
     cx_foreach(JMAPMailBox *, mbox, i) {
         printf("{%s}: %s (%s)\n", mbox->id, mbox->name, mbox->role);
+        if(!cx_strcmp(mbox->role, "inbox")) {
+            inbox = mbox;
+        }
+    }
+    
+    if(inbox) {
+        printf("\n");
+        CxList *mails = jmap_mailbox_get_mails(inbox);
+        i = cxListIterator(mails);
+        cx_foreach(JMAPMail *, mail, i) {
+            printf("{%s}: %s\n", mail->id, mail->subject);
+        }
     }
     
     return 0;
--- a/libidav/jmap_mail.c	Fri Jul 10 17:56:21 2026 +0200
+++ b/libidav/jmap_mail.c	Sat Jul 11 20:57:23 2026 +0200
@@ -97,6 +97,7 @@
         }
         
         JMAPMailBox *mbox = cxZalloc(a, sizeof(JMAPMailBox));
+        mbox->session = sn;
         mbox->id = cx_strdup_a(a, id->string).ptr;
         if(cxJsonIsString(name)) {
             mbox->name = cx_strdup_a(a, name->string).ptr;
@@ -119,3 +120,75 @@
         return list;
     }
 }
+
+CxList* jmap_mailbox_get_mails(JMAPMailBox *mailbox) {
+    JMAPSession *sn = mailbox->session;
+    const CxAllocator *a = sn->mp->allocator;
+    
+    CxBuffer *request = jm_email_get_request(cx_str(mailbox->id));
+    //printf("%.*s\n", (int)request->size, request->space);
+    
+    CxJsonValue *response = jm_do_api_request(sn, request);
+    cxBufferFree(request);
+    if(!response) {
+        return NULL;
+    }
+    
+    CxJsonValue *mail_list = NULL;
+    if(cxJsonIsObject(response)) {
+        CxJsonValue *method_responses = cxJsonObjGet(response, "methodResponses");
+        if(cxJsonIsArray(method_responses) && method_responses->array.size > 1) {
+            CxJsonValue *method_response1 = method_responses->array.data[1];
+            if(cxJsonIsArray(method_response1) && method_response1->array.size > 1) {
+                CxJsonValue *method = method_response1->array.data[0];
+                if(cxJsonIsString(method) && !cx_strcmp(method->string, "Email/get")) {
+                    CxJsonValue *mail_get_response_obj = method_response1->array.data[1];
+                    if(cxJsonIsObject(mail_get_response_obj)) {
+                        mail_list = cxJsonObjGet(mail_get_response_obj, "list");
+                    }
+                }
+            }
+        }
+    }
+    
+    if(!mail_list) {
+        cxJsonValueFree(response);
+        return NULL;
+    }
+    
+    CxList *list = cxArrayListCreate(a, CX_STORE_POINTERS, 16);
+    list->collection.simple_destructor = (cx_destructor_func)jmap_mailbox_free;
+    int error = 0;
+    for(size_t i=0;i<mail_list->array.size;i++) {
+        CxJsonValue *mail = mail_list->array.data[i];
+        if(!cxJsonIsObject(mail)) {
+            error = 1;
+            break;
+        }
+        
+        CxJsonValue *id = cxJsonObjGet(mail, "id");
+        CxJsonValue *subject = cxJsonObjGet(mail, "subject");
+        
+        if(!cxJsonIsString(id)) {
+            error = 1;
+            break;
+        }
+        
+        JMAPMail *email = cxZalloc(a, sizeof(JMAPMail));
+        email->session = sn;
+        email->id = cx_strdup_a(a, id->string).ptr;
+        if(cxJsonIsString(subject)) {
+            email->subject = cx_strdup_a(a, subject->string).ptr;
+        }
+        
+        cxListAdd(list, email);
+    }
+    
+    cxJsonValueFree(response);
+    if(error) {
+        cxListFree(list);
+        return NULL;
+    } else {
+        return list;
+    }
+}
\ No newline at end of file
--- a/libidav/jmap_mail.h	Fri Jul 10 17:56:21 2026 +0200
+++ b/libidav/jmap_mail.h	Sat Jul 11 20:57:23 2026 +0200
@@ -36,6 +36,7 @@
 #endif
 
 typedef struct JMAPMailBox JMAPMailBox;
+typedef struct JMAPMail    JMAPMail;
     
 struct JMAPMailBox {
     JMAPSession *session;
@@ -50,9 +51,18 @@
     uint32_t unread_threads;
 };
 
+struct JMAPMail {
+    JMAPSession *session;
+    char *id;
+    char *subject;
+    char *from;
+    time_t received_at;
+};
+
 void jmap_mailbox_free(JMAPMailBox *mailbox);
 
 CxList* jmap_mailbox_get_list(JMAPSession *sn);
+CxList* jmap_mailbox_get_mails(JMAPMailBox *mailbox);
 
 
 #ifdef __cplusplus
--- a/libidav/jmap_methods.c	Fri Jul 10 17:56:21 2026 +0200
+++ b/libidav/jmap_methods.c	Sat Jul 11 20:57:23 2026 +0200
@@ -48,6 +48,36 @@
     return buf;
 }
 
+CxBuffer* jm_email_get_request(cxstring mailbox) {
+    CxBuffer *buf = cxBufferCreate(NULL, NULL, 512, CX_BUFFER_AUTO_EXTEND | CX_BUFFER_FREE_CONTENTS);
+    
+    cxBufferPutString(buf,
+            "{\"using\":["
+                "\"urn:ietf:params:jmap:core\","
+                "\"urn:ietf:params:jmap:mail\""
+            "],\"methodCalls\":["
+                "[\"Email/query\","
+                    "{ \"filter\": { \"inMailbox\": \"");
+    cxBufferPutString(buf, mailbox);
+    cxBufferPutString(buf,
+                    "\" } },"
+                    "\"q1\" ],"
+                "[\"Email/get\", {"
+                "\"#ids\": { "
+                    "\"resultOf\": \"q1\","
+                    "\"name\": \"Email/query\","
+                    "\"path\": \"/ids\""
+                "},"
+                "\"properties\": ["
+                    "\"subject\","
+                    "\"from\","
+                    "\"receivedAt\""
+                "] }, \"g1\" ] ] }");
+                
+    
+    return buf;
+}
+
 CxJsonValue* jm_do_api_request(JMAPSession *sn, CxBuffer *request) {
     curl_easy_setopt(sn->handle, CURLOPT_URL, sn->apiUrl);
     
--- a/libidav/jmap_methods.h	Fri Jul 10 17:56:21 2026 +0200
+++ b/libidav/jmap_methods.h	Sat Jul 11 20:57:23 2026 +0200
@@ -38,6 +38,7 @@
 #endif
 
 CxBuffer* jm_mailbox_get_request(cxstring account_id);
+CxBuffer* jm_email_get_request(cxstring mailbox);
 
 CxJsonValue* jm_do_api_request(JMAPSession *sn, CxBuffer *request);
 

mercurial