Rework blogview renderer, so it can build the threads with only the information our...
[citadel.git] / webcit / msg_renderers.c
index d04959865188d830015890c6bfa9f9c1b66cefed..15abfddf5a67cd3d8e8fb7976fad4cfd4fab2ff3 100644 (file)
@@ -5,6 +5,11 @@
 CtxType CTX_MAILSUM = CTX_NONE;
 CtxType CTX_MIME_ATACH = CTX_NONE;
 
+HashList *MsgHeaderHandler = NULL;
+HashList *DflMsgHeaderHandler = NULL;
+HashList *DflEnumMsgHeaderHandler = NULL;
+
+
 static inline void CheckConvertBufs(struct wcsession *WCC)
 {
        if (WCC->ConvertBuf1 == NULL)
@@ -61,7 +66,39 @@ void DestroyMessageSummary(void *vMsg)
        free(Msg);
 }
 
+int EvaluateMsgHdrEnum(eMessageField f, message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+       void *vHdr;
+       headereval* Hdr = NULL;
+       if (GetHash(DflEnumMsgHeaderHandler, IKEY(f), &vHdr) &&
+           (vHdr != NULL)) {
+               Hdr = (headereval*)vHdr;
+       }
+       if (Hdr == NULL)
+               return -1;
+       Hdr->evaluator(Msg, HdrLine, FoundCharset);
+       return Hdr->Type;
+}
 
+int EvaluateMsgHdr(const char *HeaderName, long HdrNLen, message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+       void *vHdr;
+       headereval* Hdr = NULL;
+       if (HdrNLen == 4) {
+               if (GetHash(DflMsgHeaderHandler, HeaderName, HdrNLen, &vHdr) &&
+                   (vHdr != NULL)) {
+                       Hdr = (headereval*)vHdr;
+               }
+       }
+       if (Hdr == NULL && GetHash(MsgHeaderHandler, HeaderName, HdrNLen, &vHdr) &&
+           (vHdr != NULL)) {
+               Hdr = (headereval*)vHdr;
+       }
+       if (Hdr == NULL)
+               return -1;
+       Hdr->evaluator(Msg, HdrLine, FoundCharset);
+       return Hdr->Type;
+}
 
 void RegisterMsgHdr(const char *HeaderName, long HdrNLen, ExamineMsgHeaderFunc evaluator, int type)
 {
@@ -69,6 +106,15 @@ void RegisterMsgHdr(const char *HeaderName, long HdrNLen, ExamineMsgHeaderFunc e
        ev = (headereval*) malloc(sizeof(headereval));
        ev->evaluator = evaluator;
        ev->Type = type;
+
+       if (HdrNLen == 4) {
+               eMessageField f;
+               if (GetFieldFromMnemonic(&f, HeaderName)) {
+                       Put(DflMsgHeaderHandler, HeaderName, HdrNLen, ev, NULL);
+                       Put(DflEnumMsgHeaderHandler, IKEY(f), ev, reference_free_handler);
+                       return;
+               }
+       }
        Put(MsgHeaderHandler, HeaderName, HdrNLen, ev, NULL);
 }
 
@@ -242,6 +288,12 @@ void examine_content_encoding(message_summary *Msg, StrBuf *HdrLine, StrBuf *Fou
 /* TODO: do we care? */
 }
 
+
+void examine_exti(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
+{
+       /* we don't care */
+}
+
 void examine_nhdr(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
 {
        Msg->nhdr = 0;
@@ -803,8 +855,6 @@ void examine_content_lengh(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundC
 
 void examine_content_type(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCharset)
 {
-       void *vHdr;
-       headereval *Hdr;
        StrBuf *Token;
        StrBuf *Value;
        const char* sem;
@@ -840,12 +890,8 @@ void examine_content_type(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCh
                        }
                        StrBufTrim(Token);
 
-                       if (GetHash(MsgHeaderHandler, SKEY(Token), &vHdr) &&
-                           (vHdr != NULL)) {
-                               Hdr = (headereval*)vHdr;
-                               Hdr->evaluator(Msg, Value, FoundCharset);
-                       }
-                       else syslog(LOG_WARNING, "don't know how to handle content type sub-header[%s]\n", ChrPtr(Token));
+                       if (EvaluateMsgHdr(SKEY(Token), Msg, Value, FoundCharset) < 0)
+                               syslog(LOG_WARNING, "don't know how to handle content type sub-header[%s]\n", ChrPtr(Token));
                }
                FreeStrBuf(&Token);
                FreeStrBuf(&Value);
@@ -855,8 +901,6 @@ void examine_content_type(message_summary *Msg, StrBuf *HdrLine, StrBuf *FoundCh
 
 int ReadOneMessageSummary(message_summary *Msg, StrBuf *FoundCharset, StrBuf *Buf)
 {
-       void *vHdr;
-       headereval *Hdr;
        const char *buf;
        const char *ebuf;
        int nBuf;
@@ -878,13 +922,8 @@ int ReadOneMessageSummary(message_summary *Msg, StrBuf *FoundCharset, StrBuf *Bu
                ebuf = strchr(ChrPtr(Buf), '=');
                nBuf = ebuf - buf;
                
-               if (GetHash(MsgHeaderHandler, buf, nBuf, &vHdr) &&
-                   (vHdr != NULL)) {
-                       Hdr = (headereval*)vHdr;
-                       StrBufCutLeft(Buf, nBuf + 1);
-                       Hdr->evaluator(Msg, Buf, FoundCharset);
-               }
-               else syslog(LOG_INFO, "Don't know how to handle Message Headerline [%s]", ChrPtr(Buf));
+               if (EvaluateMsgHdr(buf, nBuf, Msg, Buf, FoundCharset) < 0)
+                       syslog(LOG_INFO, "Don't know how to handle Message Headerline [%s]", ChrPtr(Buf));
        }
        return 1;
 }
@@ -1373,6 +1412,59 @@ readloop_struct rlid[] = {
        { {HKEY("readlt")},     servcmd_readlt          }
 };
 
+const char* fieldMnemonics[] = {
+       "from", /* A -> eAuthor       */
+       "exti", /* E -> eXclusivID    */
+       "rfca", /* F -> erFc822Addr   */
+       "hnod", /* H -> eHumanNode    */
+       "msgn", /* I -> emessageId    */
+       "jrnl", /* J -> eJournal      */
+       "rep2", /* K -> eReplyTo      */
+       "list", /* L -> eListID       */
+       "text", /* M -> eMesageText   */
+       "node", /* N -> eNodeName     */
+       "room", /* O -> eOriginalRoom */
+       "path", /* P -> eMessagePath  */
+       "rcpt", /* R -> eRecipient    */
+       "spec", /* S -> eSpecialField */
+       "time", /* T -> eTimestamp    */
+       "subj", /* U -> eMsgSubject   */
+       "nvto", /* V -> eenVelopeTo   */
+       "wefw", /* W -> eWeferences   */
+       "cccc", /* Y -> eCarbonCopY   */
+       "nhdr", /* % -> eHeaderOnly   */
+       "type", /* % -> eFormatType   */
+       "part", /* % -> eMessagePart  */
+       "suff", /* % -> eSubFolder    */
+       "pref"  /* % -> ePevious      */
+};
+HashList *msgKeyLookup = NULL;
+
+int GetFieldFromMnemonic(eMessageField *f, const char* c)
+{
+       void *v = NULL;
+       if (GetHash(msgKeyLookup, c, 4, &v)) {
+               *f = (eMessageField) v;
+               return 1;
+       }
+       return 0;
+}
+
+void FillMsgKeyLookupTable(void)
+{
+       long i = 0;
+
+       msgKeyLookup = NewHash (1, FourHash);
+
+       while (i != eLastHeader) {
+               if (fieldMnemonics[i] != NULL) {
+                       Put(msgKeyLookup, fieldMnemonics[i], 4, (void*)i, reference_free_handler);
+               }
+               i++;
+       }
+}
+
+
 
 void 
 InitModule_MSGRENDERERS
@@ -1489,6 +1581,7 @@ InitModule_MSGRENDERERS
 
        /* these headers are citserver replies to MSG4 and friends. one evaluator for each */
        RegisterMsgHdr(HKEY("nhdr"), examine_nhdr, 0);
+       RegisterMsgHdr(HKEY("exti"), examine_exti, 0);
        RegisterMsgHdr(HKEY("type"), examine_type, 0);
        RegisterMsgHdr(HKEY("from"), examine_from, 0);
        RegisterMsgHdr(HKEY("subj"), examine_subj, 0);
@@ -1529,22 +1622,28 @@ void
 ServerStartModule_MSGRENDERERS
 (void)
 {
+       DflMsgHeaderHandler = NewHash (1, FourHash);
+       DflEnumMsgHeaderHandler = NewHash (1, Flathash);
        MsgHeaderHandler = NewHash(1, NULL);
        MimeRenderHandler = NewHash(1, NULL);
        ReadLoopHandler = NewHash(1, NULL);
+       FillMsgKeyLookupTable();
 }
 
 void 
 ServerShutdownModule_MSGRENDERERS
 (void)
 {
+       DeleteHash(&DflMsgHeaderHandler);
+       DeleteHash(&DflEnumMsgHeaderHandler);
+
+
        DeleteHash(&MsgHeaderHandler);
        DeleteHash(&MimeRenderHandler);
        DeleteHash(&ReadLoopHandler);
+       DeleteHash(&msgKeyLookup);
 }
 
-
-
 void 
 SessionDestroyModule_MSGRENDERERS
 (wcsession *sess)