# HG changeset patch # User Olaf Wintermann # Date 1783796243 -7200 # Node ID 57167625bfdd53dc5fed2f84862eea795d0a085b # Parent 0bcf3d69b37af738df9e55483cef1ad27d1746d4 add jmap_mailbox_get_mails diff -r 0bcf3d69b37a -r 57167625bfdd jmap/jmmail.c --- 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; diff -r 0bcf3d69b37a -r 57167625bfdd libidav/jmap_mail.c --- 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;iarray.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 diff -r 0bcf3d69b37a -r 57167625bfdd libidav/jmap_mail.h --- 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 diff -r 0bcf3d69b37a -r 57167625bfdd libidav/jmap_methods.c --- 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); diff -r 0bcf3d69b37a -r 57167625bfdd libidav/jmap_methods.h --- 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);