* evaluate_mime_part(): also evaluate sub-parts
[citadel.git] / webcit / msg_renderers.c
index c7cb3670ede8325451db6bfc355f022c0c7e42a6..d53d7199a4f47fb34df2edd91c86a72bb6aa0102 100644 (file)
@@ -261,8 +261,6 @@ void tmplput_MAIL_SUMM_FROM(StrBuf *Target, WCTemplputParams *TP)
        StrBufAppendTemplate(Target, TP, Msg->from, 0);
 }
 
-
-
 void examine_subj(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
 {
        FreeStrBuf(&Msg->subj);
@@ -270,14 +268,29 @@ void examine_subj(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
        StrBuf_RFC822_to_Utf8(Msg->subj, HdrLine, WC->DefaultCharset, FoundCharset);
 }
 void tmplput_MAIL_SUMM_SUBJECT(StrBuf *Target, WCTemplputParams *TP)
-{/*////TODO: Fwd: and RE: filter!!*/
-
+{
        message_summary *Msg = (message_summary*) CTX;
+
+       if (TP->Tokens->nParameters == 4)
+       {
+               const char *pch;
+               long len;
+               
+               GetTemplateTokenString(Target, TP, 3, &pch, &len);
+               if ((len > 0)&&
+                   (strstr(ChrPtr(Msg->subj), pch) == NULL))
+               {
+                       GetTemplateTokenString(Target, TP, 2, &pch, &len);
+                       StrBufAppendBufPlain(Target, pch, len, 0);
+               }
+       }
        StrBufAppendTemplate(Target, TP, Msg->subj, 0);
 }
 int Conditional_MAIL_SUMM_SUBJECT(StrBuf *Target, WCTemplputParams *TP)
 {
        message_summary *Msg = (message_summary*) CTX;
+
+
        return StrLength(Msg->subj) > 0;
 }
 
@@ -335,7 +348,7 @@ void tmplput_MAIL_SUMM_CCCC(StrBuf *Target, WCTemplputParams *TP)
 void examine_room(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
 {
        if ((StrLength(HdrLine) > 0) &&
-           (strcasecmp(ChrPtr(HdrLine), ChrPtr(WC->wc_roomname)))) {
+           (strcasecmp(ChrPtr(HdrLine), ChrPtr(WC->CurRoom.name)))) {
                FreeStrBuf(&Msg->Room);
                Msg->Room = NewStrBufDup(HdrLine);              
        }
@@ -373,7 +386,7 @@ void examine_node(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
        wcsession *WCC = WC;
 
        if ( (StrLength(HdrLine) > 0) &&
-            ((WC->room_flags & QR_NETWORK)
+            ((WC->CurRoom.QRFlags & QR_NETWORK)
              || ((strcasecmp(ChrPtr(HdrLine), ChrPtr(WCC->serv_info->serv_nodename))
                   && (strcasecmp(ChrPtr(HdrLine), ChrPtr(WCC->serv_info->serv_fqdn))))))) {
                FreeStrBuf(&Msg->OtherNode);
@@ -449,6 +462,12 @@ void tmplput_MAIL_SUMM_DATE_BRIEF(StrBuf *Target, WCTemplputParams *TP)
        StrBufAppendBufPlain(Target, datebuf, -1, 0);
 }
 
+void tmplput_MAIL_SUMM_EUID(StrBuf *Target, WCTemplputParams *TP)
+{
+       message_summary *Msg = (message_summary*) CTX;
+       StrBufAppendTemplate(Target, TP, Msg->euid, 0);
+}
+
 void tmplput_MAIL_SUMM_DATE_FULL(StrBuf *Target, WCTemplputParams *TP)
 {
        char datebuf[64];
@@ -489,14 +508,15 @@ void render_MAIL(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset
 void render_MIME_VCard(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
 {
        wcsession *WCC = WC;
-       MimeLoadData(Mime);
+       if (StrLength(Mime->Data) == 0)
+               MimeLoadData(Mime);
        if (StrLength(Mime->Data) > 0) {
                StrBuf *Buf;
                Buf = NewStrBuf();
                /** If it's my vCard I can edit it */
-               if (    (!strcasecmp(ChrPtr(WCC->wc_roomname), USERCONFIGROOM))
-                       || (!strcasecmp(&(ChrPtr(WCC->wc_roomname)[11]), USERCONFIGROOM))
-                       || (WC->wc_view == VIEW_ADDRESSBOOK)
+               if (    (!strcasecmp(ChrPtr(WCC->CurRoom.name), USERCONFIGROOM))
+                       || (!strcasecmp(&(ChrPtr(WCC->CurRoom.name)[11]), USERCONFIGROOM))
+                       || (WC->CurRoom.view == VIEW_ADDRESSBOOK)
                        ) {
                        StrBufAppendPrintf(Buf, "<a href=\"edit_vcard?msgnum=%ld?partnum=%s\">",
                                Mime->msgnum, ChrPtr(Mime->PartNum));
@@ -504,7 +524,7 @@ void render_MIME_VCard(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundC
                }
 
                /* In all cases, display the full card */
-               display_vcard(Buf, Mime->Data, 0, 1, NULL, Mime->msgnum);
+               display_vcard(Buf, Mime, 0, 1, NULL, -1);
                FreeStrBuf(&Mime->Data);
                Mime->Data = Buf;
        }
@@ -513,7 +533,8 @@ void render_MIME_VCard(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundC
 
 void render_MIME_VNote(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCharset)
 {
-       MimeLoadData(Mime);
+       if (StrLength(Mime->Data) == 0)
+               MimeLoadData(Mime);
        if (StrLength(Mime->Data) > 0) {
                struct vnote *v;
                StrBuf *Buf;
@@ -558,6 +579,7 @@ void render_MIME_ICS(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCha
 
 void examine_mime_part(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
 {
+       const char *Ptr = NULL;
        wc_mime_attachment *Mime;
        StrBuf *Buf;
        
@@ -567,17 +589,17 @@ void examine_mime_part(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundChars
        Buf = NewStrBuf();
 
        Mime->Name = NewStrBuf();
-       StrBufExtract_token(Buf, HdrLine, 0, '|');
+       StrBufExtract_NextToken(Buf, HdrLine, &Ptr, '|');
        StrBuf_RFC822_to_Utf8(Mime->Name, Buf, WC->DefaultCharset, FoundCharset);
        StrBufTrim(Mime->Name);
 
-       StrBufExtract_token(Buf, HdrLine, 1, '|');
+       StrBufExtract_NextToken(Buf, HdrLine, &Ptr, '|');
        Mime->FileName = NewStrBuf();
        StrBuf_RFC822_to_Utf8(Mime->FileName, Buf, WC->DefaultCharset, FoundCharset);
        StrBufTrim(Mime->FileName);
 
        Mime->PartNum = NewStrBuf();
-       StrBufExtract_token(Mime->PartNum, HdrLine, 2, '|');
+       StrBufExtract_NextToken(Mime->PartNum, HdrLine, &Ptr, '|');
        StrBufTrim(Mime->PartNum);
        if (strchr(ChrPtr(Mime->PartNum), '.') != NULL) 
                Mime->level = 2;
@@ -585,18 +607,24 @@ void examine_mime_part(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundChars
                Mime->level = 1;
 
        Mime->Disposition = NewStrBuf();
-       StrBufExtract_token(Mime->Disposition, HdrLine, 3, '|');
+       StrBufExtract_NextToken(Mime->Disposition, HdrLine, &Ptr, '|');
 
        Mime->ContentType = NewStrBuf();
-       StrBufExtract_token(Mime->ContentType, HdrLine, 4, '|');
+       StrBufExtract_NextToken(Mime->ContentType, HdrLine, &Ptr, '|');
        StrBufTrim(Mime->ContentType);
        StrBufLowerCase(Mime->ContentType);
-
        if (!strcmp(ChrPtr(Mime->ContentType), "application/octet-stream")) {
                StrBufPlain(Mime->ContentType, 
                            GuessMimeByFilename(SKEY(Mime->FileName)), -1);
        }
-       Mime->length = StrBufExtract_int(HdrLine, 5, '|');
+
+       Mime->length = StrBufExtractNext_int(HdrLine, &Ptr, '|');
+
+       StrBufSkip_NTokenS(HdrLine, &Ptr, '|', 1);  /* cbid?? */
+
+       Mime->Charset = NewStrBuf();
+       StrBufExtract_NextToken(Mime->Charset, HdrLine, &Ptr, '|');
+
 
        if ( (StrLength(Mime->FileName) == 0) && (StrLength(Mime->Name) > 0) ) {
                StrBufAppendBuf(Mime->FileName, Mime->Name, 0);
@@ -622,7 +650,7 @@ void evaluate_mime_part(message_summary *Msg, wc_mime_attachment *Mime)
        void *vMimeRenderer;
 
        /* just print the root-node */
-       if ((Mime->level == 1) &&
+       if ((Mime->level >= 1) &&
            GetHash(MimeRenderHandler, SKEY(Mime->ContentType), &vMimeRenderer) &&
            vMimeRenderer != NULL)
        {
@@ -631,14 +659,14 @@ void evaluate_mime_part(message_summary *Msg, wc_mime_attachment *Mime)
                        Msg->Submessages = NewHash(1,NULL);
                Put(Msg->Submessages, SKEY(Mime->PartNum), Mime, reference_free_handler);
        }
-       else if ((Mime->level == 1) &&
+       else if ((Mime->level >= 1) &&
                 (!strcasecmp(ChrPtr(Mime->Disposition), "inline"))
                 && (!strncasecmp(ChrPtr(Mime->ContentType), "image/", 6)) ){
                if (Msg->AttachLinks == NULL)
                        Msg->AttachLinks = NewHash(1,NULL);
                Put(Msg->AttachLinks, SKEY(Mime->PartNum), Mime, reference_free_handler);
        }
-       else if ((Mime->level == 1) &&
+       else if ((Mime->level >= 1) &&
                 (StrLength(Mime->ContentType) > 0) &&
                  ( (!strcasecmp(ChrPtr(Mime->Disposition), "attachment")) 
                    || (!strcasecmp(ChrPtr(Mime->Disposition), "inline"))
@@ -818,12 +846,18 @@ void tmplput_EDIT_WIKI_BODY(StrBuf *Target, WCTemplputParams *TP)
         long msgnum;
        StrBuf *Buf;
 
-       msgnum = locate_message_by_uid(BSTR("page"));
-       if (msgnum >= 0L) {
-               Buf = NewStrBuf();
-               read_message(Buf, HKEY("view_message_wikiedit"), msgnum, NULL, &Mime);
-               StrBufAppendTemplate(Target, TP, Buf, 1);
-               FreeStrBuf(&Buf);
+       /* Insert the existing content of the wiki page into the editor.  But we only want
+        * to do this the first time -- if the user is uploading an attachment we don't want
+        * to do it again.
+        */
+       if (!havebstr("attach_button")) {
+               msgnum = locate_message_by_uid(BSTR("page"));
+               if (msgnum >= 0L) {
+                       Buf = NewStrBuf();
+                       read_message(Buf, HKEY("view_message_wikiedit"), msgnum, NULL, &Mime);
+                       StrBufAppendTemplate(Target, TP, Buf, 1);
+                       FreeStrBuf(&Buf);
+               }
        }
 }
 
@@ -975,7 +1009,7 @@ void render_MAIL_html(wc_mime_attachment *Mime, StrBuf *RawData, StrBuf *FoundCh
 
        /* HTML is fun, but we've got to strip it first */
        output_html(ChrPtr(Mime->Charset), 
-                   (WC->wc_view == VIEW_WIKI ? 1 : 0), 
+                   (WC->CurRoom.view == VIEW_WIKI ? 1 : 0), 
                    Mime->msgnum,
                    Mime->Data, Buf);
        FreeStrBuf(&Mime->Data);
@@ -1129,6 +1163,11 @@ void servcmd_readgt(char *buf, long bufsize)
        snprintf(buf, bufsize, "MSGS GT|%s", bstr("gt"));
 }
 
+void servcmd_readlt(char *buf, long bufsize)
+{
+       snprintf(buf, bufsize, "MSGS LT|%s", bstr("lt"));
+}
+
 void servcmd_readnew(char *buf, long bufsize)
 {
        snprintf(buf, bufsize, "MSGS NEW");
@@ -1140,15 +1179,74 @@ void servcmd_readold(char *buf, long bufsize)
 }
 
 
+/* DO NOT REORDER OR REMOVE ANY OF THESE */
 readloop_struct rlid[] = {
-       { {HKEY("do_search")}, servcmd_do_search},
-       { {HKEY("headers")},   servcmd_headers},
-       { {HKEY("readfwd")},   servcmd_readfwd},
-       { {HKEY("readnew")},   servcmd_readnew},
-       { {HKEY("readold")},   servcmd_readold},
-       { {HKEY("readgt")},    servcmd_readgt}
+       { {HKEY("do_search")},  servcmd_do_search       },
+       { {HKEY("headers")},    servcmd_headers         },
+       { {HKEY("readfwd")},    servcmd_readfwd         },
+       { {HKEY("readnew")},    servcmd_readnew         },
+       { {HKEY("readold")},    servcmd_readold         },
+       { {HKEY("readgt")},     servcmd_readgt          },
+       { {HKEY("readlt")},     servcmd_readlt          }
 };
 
+
+int ParseMessageListHeaders_Detail(StrBuf *Line, 
+                                  const char **pos, 
+                                  message_summary *Msg, 
+                                  StrBuf *ConversionBuffer)
+{
+       wcsession *WCC = WC;
+
+       Msg->from = NewStrBufPlain(NULL, StrLength(Line));
+       StrBufExtract_NextToken(ConversionBuffer, Line, pos, '|');
+       if (StrLength(ConversionBuffer) != 0) {
+               /* Handle senders with RFC2047 encoding */
+               StrBuf_RFC822_to_Utf8(Msg->from, ConversionBuffer, WCC->DefaultCharset, NULL);
+       }
+                       
+       /* node name */
+       StrBufExtract_NextToken(ConversionBuffer, Line, pos, '|');
+       if ((StrLength(ConversionBuffer) !=0 ) &&
+                   ( ((WCC->CurRoom.QRFlags & QR_NETWORK)
+              || ((strcasecmp(ChrPtr(ConversionBuffer), ChrPtr(WCC->serv_info->serv_nodename))
+                   && (strcasecmp(ChrPtr(ConversionBuffer), ChrPtr(WCC->serv_info->serv_fqdn))))))))
+       {
+               StrBufAppendBufPlain(Msg->from, HKEY(" @ "), 0);
+               StrBufAppendBuf(Msg->from, ConversionBuffer, 0);
+       }
+
+       /* Internet address (not used)
+        *      StrBufExtract_token(Msg->inetaddr, Line, 4, '|');
+        */
+       StrBufSkip_NTokenS(Line, pos, '|', 1);
+       Msg->subj = NewStrBufPlain(NULL, StrLength(Line));
+
+       FlushStrBuf(ConversionBuffer);
+       /* we assume the subject is the last parameter inside of the list; 
+        * thus we don't use the tokenizer to fetch it, since it will hick up 
+        * on tokenizer chars inside of the subjects
+       StrBufExtract_NextToken(ConversionBuffer,  Line, pos, '|');
+       */
+       if (*pos != StrBufNOTNULL) {
+               StrBufPlain(ConversionBuffer, *pos, 
+                           StrLength(Line) - (*pos - ChrPtr(Line)));
+               *pos = StrBufNOTNULL;
+               if ((StrLength(ConversionBuffer) > 0) &&
+                   (*(ChrPtr(ConversionBuffer) + 
+                      StrLength(ConversionBuffer) - 1) == '|'))
+                       StrBufCutRight(ConversionBuffer, 1);
+       }
+
+       if (StrLength(ConversionBuffer) == 0)
+               StrBufAppendBufPlain(Msg->subj, _("(no subject)"), -1,0);
+       else {
+               StrBuf_RFC822_to_Utf8(Msg->subj, ConversionBuffer, WCC->DefaultCharset, NULL);
+       }
+
+       return 1;
+}
+
 /* Spit out the new summary view. This is basically a static page, so clients can cache the layout, all the dirty work is javascript :) */
 void new_summary_view(void) {
        DoTemplate(HKEY("msg_listview"),NULL,&NoCtx);
@@ -1216,6 +1314,7 @@ InitModule_MSGRENDERERS
                VIEW_MAILBOX,
                mailview_GetParamsGetServerCall,
                NULL, /// TODO: is this right?
+               ParseMessageListHeaders_Detail,
                NULL, //// ""
                mailview_RenderView_or_Tail,
                mailview_Cleanup);
@@ -1244,6 +1343,7 @@ InitModule_MSGRENDERERS
        RegisterIterator("MAIL:SUMM:MSGS", 0, NULL, iterate_get_mailsumm_All,
                         NULL,NULL, CTX_MAILSUM, CTX_NONE, IT_NOFLAG);
 
+       RegisterNamespace("MAIL:SUMM:EUID", 0, 1, tmplput_MAIL_SUMM_EUID, NULL, CTX_MAILSUM);
        RegisterNamespace("MAIL:SUMM:DATEBRIEF", 0, 0, tmplput_MAIL_SUMM_DATE_BRIEF, NULL, CTX_MAILSUM);
        RegisterNamespace("MAIL:SUMM:DATEFULL", 0, 0, tmplput_MAIL_SUMM_DATE_FULL, NULL, CTX_MAILSUM);
        RegisterNamespace("MAIL:SUMM:DATENO",  0, 0, tmplput_MAIL_SUMM_DATE_NO,  NULL, CTX_MAILSUM);
@@ -1306,7 +1406,7 @@ InitModule_MSGRENDERERS
                         NULL, NULL, CTX_MIME_ATACH, CTX_NONE, IT_NOFLAG);
 
        /* mime renderers translate an attachment into webcit viewable html text */
-       RegisterMimeRenderer(HKEY("message/rfc822"), render_MAIL, 1, 150);
+       RegisterMimeRenderer(HKEY("message/rfc822"), render_MAIL, 0, 150);
        RegisterMimeRenderer(HKEY("text/vnote"), render_MIME_VNote, 1, 300);
        RegisterMimeRenderer(HKEY("text/x-vcard"), render_MIME_VCard, 1, 201);
        RegisterMimeRenderer(HKEY("text/vcard"), render_MIME_VCard, 1, 200);