"
- "
\n");
- do_template("endbox", NULL);
wDumpContent(1);
if (Msg != NULL) {
DestroyMessageSummary(Msg);
@@ -1064,38 +698,36 @@ void edit_vcard(void) {
do_edit_vcard(msgnum, partnum, NULL, NULL, "", NULL);
}
-
-
/*
* parse edited vcard from the browser
*/
void submit_vcard(void) {
- wcsession *WCC = WC;
struct vCard *v;
char *serialized_vcard;
- char buf[SIZ];
StrBuf *Buf;
- int i;
+ const StrBuf *ForceRoom;
+ HashList* postVcard;
+ HashPos *it, *itSub;
+ const char *Key;
+ long len;
+ void *pv;
+ StrBuf *SubStr;
+ const StrBuf *s;
+ const char *Pos = NULL;
if (!havebstr("ok_button")) {
- readloop(readnew);
+ readloop(readnew, eUseDefault);
return;
}
if (havebstr("force_room")) {
- if (gotoroom(sbstr("force_room")) != 200) {
- StrBufAppendBufPlain(WCC->ImportantMsg,
- _("Unable to enter the room to save your message"),
- -1, 0);
- StrBufAppendBufPlain(WCC->ImportantMsg,
- HKEY(": "), 0);
- StrBufAppendBuf(WCC->ImportantMsg, sbstr("force_room"), 0);
- StrBufAppendBufPlain(WCC->ImportantMsg,
- HKEY("; "), 0);
-
- StrBufAppendBufPlain(WCC->ImportantMsg,
- _("Aborting."),
- -1, 0);
+ ForceRoom = sbstr("force_room");
+ if (gotoroom(ForceRoom) != 200) {
+ AppendImportantMessage(_("Unable to enter the room to save your message"), -1);
+ AppendImportantMessage(HKEY(": "));
+ AppendImportantMessage(SKEY(ForceRoom));
+ AppendImportantMessage(HKEY("; "));
+ AppendImportantMessage(_("Aborting."), -1);
if (!strcmp(bstr("return_to"), "select_user_to_edit")) {
select_user_to_edit(NULL);
@@ -1107,86 +739,114 @@ void submit_vcard(void) {
http_redirect(bstr("return_to"));
}
else {
- readloop(readnew);
+ readloop(readnew, eUseDefault);
}
return;
}
}
- sprintf(buf, "ENT0 1|||4||");
- serv_puts(buf);
- serv_getln(buf, sizeof buf);
- if (buf[0] != '4') {
+ postVcard = getSubStruct(HKEY("VC"));
+ if (postVcard == NULL) {
+ AppendImportantMessage(_("An error has occurred."), -1);
+ edit_vcard();
+ return;/*/// more details*/
+ }
+
+ Buf = NewStrBuf();
+ serv_write(HKEY("ENT0 1|||4\n"));
+ if (!StrBuf_ServGetln(Buf) && (GetServerStatus(Buf, NULL) != 4))
+ {
edit_vcard();
return;
}
-
+
/* Make a vCard structure out of the data supplied in the form */
- Buf = NewStrBuf();
StrBufPrintf(Buf, "begin:vcard\r\n%s\r\nend:vcard\r\n",
bstr("extrafields")
);
v = VCardLoad(Buf); /* Start with the extra fields */
- FreeStrBuf(&Buf);
if (v == NULL) {
- safestrncpy(WCC->ImportantMessage,
- _("An error has occurred."),
- sizeof WCC->ImportantMessage
- );
+ AppendImportantMessage(_("An error has occurred."), -1);
edit_vcard();
+ FreeStrBuf(&Buf);
return;
}
- snprintf(buf, sizeof buf, "%s;%s;%s;%s;%s",
- bstr("lastname"),
- bstr("firstname"),
- bstr("middlename"),
- bstr("prefix"),
- bstr("suffix") );
- vcard_add_prop(v, "n", buf);
-
- vcard_add_prop(v, "title", bstr("title"));
- vcard_add_prop(v, "fn", bstr("fullname"));
- vcard_add_prop(v, "org", bstr("org"));
-
- snprintf(buf, sizeof buf, "%s;%s;%s;%s;%s;%s;%s",
- bstr("pobox"),
- bstr("extadr"),
- bstr("street"),
- bstr("city"),
- bstr("state"),
- bstr("zipcode"),
- bstr("country") );
- vcard_add_prop(v, "adr", buf);
-
- vcard_add_prop(v, "tel;home", bstr("hometel"));
- vcard_add_prop(v, "tel;work", bstr("worktel"));
- vcard_add_prop(v, "tel;fax", bstr("faxtel"));
- vcard_add_prop(v, "tel;cell", bstr("mobiletel"));
- vcard_add_prop(v, "email;internet", bstr("primary_inetemail"));
-
- for (i=0; i
Sub != NULL){
+ vcField *Sub;
+ FlushStrBuf(SubStr);
+ itSub = GetNewHashPos(DefineToToken, 0);
+ while (GetNextHashPos(DefineToToken, itSub, &len, &Key, &pv) &&
+ (pv != NULL))
+ {
+ Sub = (vcField*) pv;
+ if (Sub->parentCVal == t->cval) {
+ if (StrLength(SubStr) > 0)
+ StrBufAppendBufPlain(SubStr, HKEY(";"), 0);
+
+
+
+ blen = snprintf(buf, sizeof(buf), "%ld", Sub->cval);
+ s = SSubBstr(postVcard, buf, blen);
+
+ if ((s != NULL) && (StrLength(s) > 0)) {
+ /// todo: utf8 qp
+ StrBufAppendBuf(SubStr, s, 0);
+ }
+ }
+ }
+ if (StrLength(SubStr) > 0) {
+ vcard_add_prop(v, t->STR.Key, ChrPtr(SubStr));
+ }
+ DeleteHashPos(&itSub);
+ }
+ else if (t->parentCVal == 0) {
+ blen = snprintf(buf, sizeof(buf), "%ld", t->cval);
+ s = SSubBstr(postVcard, buf, blen);
+
+ if ((s != NULL) && (StrLength(s) > 0)) {
+ vcard_add_prop(v, t->STR.Key, ChrPtr(s));
+ }
+ }
+ }
+ DeleteHashPos(&it);
+
+ s = sbstr("other_inetemail");
+ if (StrLength(s) > 0) {
+ FlushStrBuf(SubStr);
+ while (StrBufSipLine(SubStr, s, &Pos), ((Pos!=StrBufNOTNULL) && (Pos!=NULL)) ) {
+ if (StrLength(SubStr) > 0) {
+ vcard_add_prop(v, "email;internet", ChrPtr(SubStr));
+ }
}
}
+ FreeStrBuf(&SubStr);
+
+
serialized_vcard = vcard_serialize(v);
vcard_free(v);
if (serialized_vcard == NULL) {
- safestrncpy(WCC->ImportantMessage,
- _("An error has occurred."),
- sizeof WCC->ImportantMessage
- );
+ AppendImportantMessage(_("An error has occurred."), -1);
edit_vcard();
+ FreeStrBuf(&Buf);
return;
}
- serv_puts("Content-type: text/x-vcard; charset=UTF-8");
- serv_puts("");
+ printf("%s", serialized_vcard);
+ serv_write(HKEY("Content-type: text/x-vcard; charset=UTF-8\n"));
+ serv_write(HKEY("\n"));
serv_printf("%s\r\n", serialized_vcard);
- serv_puts("000");
+ serv_write(HKEY("000\n"));
free(serialized_vcard);
if (!strcmp(bstr("return_to"), "select_user_to_edit")) {
@@ -1199,53 +859,18 @@ void submit_vcard(void) {
http_redirect(bstr("return_to"));
}
else {
- readloop(readnew);
+ readloop(readnew, eUseDefault);
}
+ FreeStrBuf(&Buf);
}
-
-
-/*
- * Extract an embedded photo from a vCard for display on the client
- */
-void display_vcard_photo_img(void)
-{
- long msgnum = 0L;
- StrBuf *vcard;
- struct vCard *v;
- char *photosrc;
- const char *contentType;
- wcsession *WCC = WC;
-
- msgnum = StrBufExtract_long(WCC->Hdr->HR.ReqLine, 0, '/');
-
- vcard = load_mimepart(msgnum,"1");
- v = VCardLoad(vcard);
-
- photosrc = vcard_get_prop(v, "PHOTO", 1,0,0);
- FlushStrBuf(WCC->WBuf);
- StrBufAppendBufPlain(WCC->WBuf, photosrc, -1, 0);
- if (StrBufDecodeBase64(WCC->WBuf) <= 0) {
- FlushStrBuf(WCC->WBuf);
-
- hprintf("HTTP/1.1 500 %s\n","Unable to get photo");
- output_headers(0, 0, 0, 0, 0, 0);
- hprintf("Content-Type: text/plain\r\n");
- begin_burst();
- wc_printf(_("Could Not decode vcard photo\n"));
- end_burst();
- return;
- }
- contentType = GuessMimeType(ChrPtr(WCC->WBuf), StrLength(WCC->WBuf));
- http_transmit_thing(contentType, 0);
- free(v);
- free(photosrc);
-}
+/******************************************************************************
+ * Render Addressbooks *
+ ******************************************************************************/
typedef struct _vcardview_struct {
long is_singlecard;
- addrbookent *addrbook;
- long num_ab;
+ HashList *addrbook;
} vcardview_struct;
@@ -1253,7 +878,9 @@ int vcard_GetParamsGetServerCall(SharedMessageStatus *Stat,
void **ViewSpecific,
long oper,
char *cmd,
- long len)
+ long len,
+ char *filter,
+ long flen)
{
vcardview_struct *VS;
@@ -1263,6 +890,7 @@ int vcard_GetParamsGetServerCall(SharedMessageStatus *Stat,
VS->is_singlecard = ibstr("is_singlecard");
if (VS->is_singlecard != 1) {
+ VS->addrbook = NewHash(0, NULL);
if (oper == do_search) {
snprintf(cmd, len, "MSGS SEARCH|%s", bstr("query"));
}
@@ -1280,36 +908,141 @@ int vcard_LoadMsgFromServer(SharedMessageStatus *Stat,
int is_new,
int i)
{
+ WCTemplputParams *TP = NULL;
+ WCTemplputParams SubTP;
vcardview_struct *VS;
- char *ab_name;
+ wc_mime_attachment *VCMime = NULL;
+ struct vCard *v;
+ addrbookent* abEntry;
VS = (vcardview_struct*) *ViewSpecific;
- ab_name = NULL;
- fetch_ab_name(Msg, &ab_name);
- if (ab_name == NULL)
+ VCMime = load_vcard(Msg);
+ if (VCMime == NULL)
return 0;
- ++VS->num_ab;
- VS->addrbook = realloc(VS->addrbook,
- (sizeof(addrbookent) * VS->num_ab) );
- safestrncpy(VS->addrbook[VS->num_ab-1].ab_name, ab_name,
- sizeof(VS->addrbook[VS->num_ab-1].ab_name));
- VS->addrbook[VS->num_ab-1].ab_msgnum = Msg->msgnum;
- free(ab_name);
+
+ v = VCardLoad(VCMime->Data);
+
+ if (v == NULL) return 0;
+
+ abEntry = (addrbookent*) malloc(sizeof(addrbookent));
+ memset(abEntry, 0, sizeof(addrbookent));
+ abEntry->name = NewStrBuf();
+ abEntry->VC = NewHash(0, lFlathash);
+ abEntry->ab_msgnum = Msg->msgnum;
+
+ parse_vcard(WC->WBuf, v, abEntry->VC, VCMime);
+
+ memset(&SubTP, 0, sizeof(WCTemplputParams));
+ StackContext(TP, &SubTP, abEntry, CTX_VCARD, 0, NULL);
+
+ // No, don't display the name, it just shits all over the screen
+ // DoTemplate(HKEY("vcard_list_name"), WC->WBuf, &SubTP);
+
+ UnStackContext(&SubTP);
+
+ if (StrLength(abEntry->name) == 0) {
+ StrBufPlain(abEntry->name, _("(no name)"), -1);
+ }
+
+ syslog(LOG_DEBUG, "abEntry->name : %s", ChrPtr(abEntry->name));
+
+ vcard_free(v);
+
+ Put(VS->addrbook, SKEY(abEntry->name), abEntry, deleteAbEnt);
return 0;
}
+/*
+ * Render the address book using info we gathered during the scan
+ *
+ * addrbook the addressbook to render
+ * num_ab the number of the addressbook
+ */
+static int NAMESPERPAGE = 60;
+void do_addrbook_view(vcardview_struct* VS) {
+ long i = 0;
+ int num_pages = 0;
+ int tabfirst = 0;
+ int tablast = 0;
+ StrBuf **tablabels;
+ int num_ab = GetCount(VS->addrbook);
+ HashList *headlines;
+
+ WCTemplputParams *TP = NULL;
+ WCTemplputParams SubTP;
+
+ memset(&SubTP, 0, sizeof(WCTemplputParams));
+
+ if (num_ab == 0) {
+ do_template("vcard_list_empty");
+ return;
+ }
+
+ if (num_ab > 1) {
+ SortByHashKey(VS->addrbook, 1);
+ }
+
+ num_pages = (GetCount(VS->addrbook) / NAMESPERPAGE) + 1;
+
+ tablabels = malloc(num_pages * sizeof (StrBuf *));
+ if (tablabels == NULL) {
+ return;
+ }
+
+ headlines = NewHash(0, lFlathash);
+ for (i=0; i (num_ab - 1)) tablast = (num_ab - 1);
+
+ headline = NewStrBufPlain(NULL, StrLength(v1) + StrLength(v2) + 10);
+ if (GetHashAt(VS->addrbook, tabfirst, &hklen1, &c1, &v1)) {
+ a1 = (addrbookent*) v1;
+ StrBufAppendBuf(headline, a1->name, 0);
+ StrBuf_Utf8StrCut(headline, 3);
+ if (GetHashAt(VS->addrbook, tablast, &hklen2, &c2, &v2)) {
+
+ a2 = (addrbookent*) v2;
+ StrBufAppendBufPlain(headline, HKEY(" - "), 0);
+ StrBufAppendBuf(headline, a2->name, 0);
+ StrBuf_Utf8StrCut(headline, 9);
+ }
+ }
+ tablabels[i] = headline;
+ Put(headlines, LKEY(i), headline, HFreeStrBuf);
+ }
+ StrTabbedDialog(WC->WBuf, num_pages, tablabels);
+ StackContext(TP, &SubTP, VS->addrbook, CTX_VCARD_LIST, 0, NULL);
+
+ DoTemplate(HKEY("vcard_list"), WC->WBuf, &SubTP);
+ UnStackContext(&SubTP);
+ DeleteHash(&headlines);
+ free(tablabels);
+}
+
+
+
int vcard_RenderView_or_Tail(SharedMessageStatus *Stat, void **ViewSpecific, long oper)
{
const StrBuf *Mime;
vcardview_struct *VS;
VS = (vcardview_struct*) *ViewSpecific;
- if (VS->is_singlecard)
- read_message(WC->WBuf, HKEY("view_message"), lbstr("startmsg"), NULL, &Mime);
- else
- do_addrbook_view(VS->addrbook, VS->num_ab); /* Render the address book */
+ if (VS->is_singlecard) {
+ read_message(WC->WBuf, HKEY("view_message"), lbstr("startmsg"), NULL, &Mime, NULL);
+ }
+ else {
+ do_addrbook_view(VS); /* Render the address book */
+ }
return 0;
}
@@ -1319,27 +1052,144 @@ int vcard_Cleanup(void **ViewSpecific)
VS = (vcardview_struct*) *ViewSpecific;
wDumpContent(1);
- if ((VS != NULL) &&
- (VS->addrbook != NULL))
- free(VS->addrbook);
- if (VS != NULL)
+ if ((VS != NULL) && (VS->addrbook != NULL)) {
+ DeleteHash(&VS->addrbook);
+ }
+ if (VS != NULL) {
free(VS);
+ }
+
return 0;
}
+void render_MIME_VCard(StrBuf *Target, WCTemplputParams *TP, StrBuf *FoundCharset)
+{
+ wc_mime_attachment *Mime = (wc_mime_attachment *) CTX(CTX_MIME_ATACH);
+ if (StrLength(Mime->Data) == 0) {
+ MimeLoadData(Mime);
+ }
+ if (StrLength(Mime->Data) > 0) {
+ struct vCard *v;
+ StrBuf *Buf;
+
+ Buf = NewStrBuf();
+ /** If it's my vCard I can edit it */
+ if ( (!strcasecmp(ChrPtr(WC->CurRoom.name), USERCONFIGROOM))
+ || ((StrLength(WC->CurRoom.name) > 11) &&
+ (!strcasecmp(&(ChrPtr(WC->CurRoom.name)[11]), USERCONFIGROOM)))
+ || (WC->CurRoom.view == VIEW_ADDRESSBOOK)
+ ) {
+ StrBufAppendPrintf(Buf, "",
+ Mime->msgnum, ChrPtr(Mime->PartNum));
+ StrBufAppendPrintf(Buf, "[%s]", _("edit"));
+ }
+
+ /* In all cases, display the full card */
+
+ v = VCardLoad(Mime->Data);
+
+ if (v != NULL) {
+ WCTemplputParams *TP = NULL;
+ WCTemplputParams SubTP;
+ addrbookent ab;
+ memset(&ab, 0, sizeof(addrbookent));
+
+ ab.VC = NewHash(0, lFlathash);
+ ab.ab_msgnum = Mime->msgnum;
+
+ parse_vcard(Target, v, ab.VC, Mime);
+
+ memset(&SubTP, 0, sizeof(WCTemplputParams));
+ StackContext(TP, &SubTP, &ab, CTX_VCARD, 0, NULL);
+
+ DoTemplate(HKEY("vcard_msg_display"), Target, &SubTP);
+ UnStackContext(&SubTP);
+ DeleteHash(&ab.VC);
+ vcard_free(v);
+
+ }
+ else {
+ StrBufPlain(Buf, _("failed to load vcard"), -1);
+ }
+ FreeStrBuf(&Mime->Data);
+ Mime->Data = Buf;
+ }
+
+}
+
+void
+ServerStartModule_VCARD
+(void)
+{
+}
+
+void
+ServerShutdownModule_VCARD
+(void)
+{
+ DeleteHash(&DefineToToken);
+ DeleteHash(&vcNames);
+ DeleteHash(&VCTokenToDefine);
+}
+
void
InitModule_VCARD
(void)
{
+ StrBuf *Prefix = NewStrBufPlain(HKEY("VC:"));
+ DefineToToken = NewHash(1, lFlathash);
+ vcNames = NewHash(1, lFlathash);
+ VCTokenToDefine = NewHash(1, NULL);
+ autoRegisterTokens(&VCEnumCounter, VCStrE, Prefix, 0, 0);
+ FreeStrBuf(&Prefix);
+
+ REGISTERTokenParamDefine(NAMESPERPAGE);
+
+
+ RegisterCTX(CTX_VCARD);
+ RegisterCTX(CTX_VCARD_LIST);
+ RegisterCTX(CTX_VCARD_TYPE);
+
RegisterReadLoopHandlerset(
VIEW_ADDRESSBOOK,
vcard_GetParamsGetServerCall,
NULL,
+ NULL,
+ NULL,
vcard_LoadMsgFromServer,
vcard_RenderView_or_Tail,
- vcard_Cleanup);
+ vcard_Cleanup,
+ NULL);
+
+ RegisterIterator("MAIL:VCARDS", 0, NULL, CtxGetVcardList, NULL, NULL, CTX_VCARD, CTX_VCARD_LIST, IT_NOFLAG);
+
+
WebcitAddUrlHandler(HKEY("edit_vcard"), "", 0, edit_vcard, 0);
WebcitAddUrlHandler(HKEY("submit_vcard"), "", 0, submit_vcard, 0);
WebcitAddUrlHandler(HKEY("vcardphoto"), "", 0, display_vcard_photo_img, NEED_URL);
-}
+ RegisterNamespace("VC:ITEM", 2, 2, tmpl_vcard_item, preeval_vcard_item, CTX_VCARD);
+ RegisterNamespace("VC:CTXITEM", 1, 1, tmpl_vcard_context_item, NULL, CTX_VCARD_TYPE);
+ RegisterNamespace("VC:NAME", 1, 1, tmpl_vcard_name_str, preeval_vcard_name_str, CTX_VCARD);
+ RegisterNamespace("VC:MSGNO", 0, 1, tmpl_vcard_msgno, NULL, CTX_VCARD);
+ RegisterNamespace("VC:CTXNAME", 1, 1, tmpl_vcard_context_name_str, NULL, CTX_VCARD_TYPE);
+ REGISTERTokenParamDefine(FlatString);
+ REGISTERTokenParamDefine(StringCluster);
+ REGISTERTokenParamDefine(PhoneNumber);
+ REGISTERTokenParamDefine(EmailAddr);
+ REGISTERTokenParamDefine(Street);
+ REGISTERTokenParamDefine(Number);
+ REGISTERTokenParamDefine(AliasFor);
+ REGISTERTokenParamDefine(Base64BinaryAttachment);
+ REGISTERTokenParamDefine(TerminateList);
+ REGISTERTokenParamDefine(Address);
+
+ RegisterConditional("VC:HAVE:TYPE", 1, conditional_VC_Havetype, CTX_VCARD);
+ RegisterConditional("COND:VC:SUPPRESS_EMAIL_FIELDS", 1, conditional_VC_SuppressEmailFields, CTX_VCARD);
+
+ RegisterFilteredIterator("VC:TYPE", 1, DefineToToken, NULL, NULL, NULL, filter_VC_ByType, CTX_VCARD_TYPE, CTX_VCARD, IT_NOFLAG);
+ RegisterFilteredIterator("VC:TYPE:ITEMS", 0, NULL, getContextVcard, NULL, NULL, filter_VC_ByContextType, CTX_STRBUF, CTX_VCARD_TYPE, IT_NOFLAG);
+
+ RegisterMimeRenderer(HKEY("text/x-vcard"), render_MIME_VCard, 1, 201);
+ RegisterMimeRenderer(HKEY("text/vcard"), render_MIME_VCard, 1, 200);
+}