");
+ wprintf("- ");
+ if (p != NULL) {
+ escputs((char *)icalproperty_get_comment(p));
+ }
+ wprintf("");
+ wprintf("\n");
+ wprintf("\n");
+ wprintf("");
wDumpContent(1);
if (created_new_vtodo) {
@@ -590,11 +776,14 @@ void display_edit_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
}
/*
- * \brief Save an edited task
- * \param supplied_vtodo the task to save
- * \param msgnum number of the mesage in our db
+ * Save an edited task
+ *
+ * supplied_vtodo the task to save
+ * msgnum number of the mesage in our db
*/
-void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
+void save_individual_task(icalcomponent *supplied_vtodo, long msgnum, char* from, int unread,
+ struct calview *calv)
+{
char buf[SIZ];
int delete_existing = 0;
icalproperty *prop;
@@ -617,9 +806,9 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
if (icalcomponent_isa(vtodo) == ICAL_VCALENDAR_COMPONENT) {
save_individual_task(
icalcomponent_get_first_component(
- vtodo, ICAL_VTODO_COMPONENT
- ), msgnum
- );
+ vtodo, ICAL_VTODO_COMPONENT),
+ msgnum, from, unread, calv
+ );
return;
}
}
@@ -628,66 +817,112 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
created_new_vtodo = 1;
}
- if (!IsEmptyStr(bstr("save_button"))) {
+ if (havebstr("save_button")) {
/** Replace values in the component with ones from the form */
while (prop = icalcomponent_get_first_property(vtodo,
- ICAL_SUMMARY_PROPERTY), prop != NULL) {
+ ICAL_SUMMARY_PROPERTY), prop != NULL) {
icalcomponent_remove_property(vtodo, prop);
icalproperty_free(prop);
}
- if (!IsEmptyStr(bstr("summary"))) {
-
- icalcomponent_add_property(vtodo,
- icalproperty_new_summary(bstr("summary")));
- } else {
- icalcomponent_add_property(vtodo,
- icalproperty_new_summary("Untitled Task"));
- }
+ if (havebstr("summary")) {
+
+ icalcomponent_add_property(vtodo,
+ icalproperty_new_summary(bstr("summary")));
+ } else {
+ icalcomponent_add_property(vtodo,
+ icalproperty_new_summary(_("Untitled Task")));
+ }
while (prop = icalcomponent_get_first_property(vtodo,
- ICAL_DESCRIPTION_PROPERTY), prop != NULL) {
+ ICAL_DESCRIPTION_PROPERTY), prop != NULL) {
icalcomponent_remove_property(vtodo, prop);
icalproperty_free(prop);
}
- icalcomponent_add_property(vtodo,
- icalproperty_new_description(bstr("description")));
+ if (havebstr("description")) {
+ icalcomponent_add_property(vtodo,
+ icalproperty_new_description(bstr("description")));
+ }
while (prop = icalcomponent_get_first_property(vtodo,
- ICAL_DTSTART_PROPERTY), prop != NULL) {
+ ICAL_DTSTART_PROPERTY), prop != NULL) {
icalcomponent_remove_property(vtodo, prop);
icalproperty_free(prop);
}
- icaltime_from_webform(&t, "dtstart");
- icalcomponent_add_property(vtodo,
- icalproperty_new_dtstart(t)
- );
-
+ if (IsEmptyStr(bstr("nodtstart"))) {
+ if (yesbstr("dtstart_time")) {
+ icaltime_from_webform(&t, "dtstart");
+ }
+ else {
+ icaltime_from_webform_dateonly(&t, "dtstart");
+ }
+ icalcomponent_add_property(vtodo,
+ icalproperty_new_dtstart(t)
+ );
+ }
+ while(prop = icalcomponent_get_first_property(vtodo,
+ ICAL_STATUS_PROPERTY), prop != NULL) {
+ icalcomponent_remove_property(vtodo,prop);
+ icalproperty_free(prop);
+ }
+ while(prop = icalcomponent_get_first_property(vtodo,
+ ICAL_PERCENTCOMPLETE_PROPERTY), prop != NULL) {
+ icalcomponent_remove_property(vtodo,prop);
+ icalproperty_free(prop);
+ }
+
+ if (havebstr("status")) {
+ icalproperty_status taskStatus = icalproperty_string_to_status(bstr("status"));
+ icalcomponent_set_status(vtodo, taskStatus);
+ icalcomponent_add_property(vtodo,
+ icalproperty_new_percentcomplete(
+ (strcasecmp(bstr("status"), "completed") ? 0 : 100)
+ )
+ );
+ }
+ else {
+ icalcomponent_add_property(vtodo, icalproperty_new_percentcomplete(0));
+ }
+ while (prop = icalcomponent_get_first_property(vtodo,
+ ICAL_CATEGORIES_PROPERTY), prop != NULL) {
+ icalcomponent_remove_property(vtodo,prop);
+ icalproperty_free(prop);
+ }
+ if (!IsEmptyStr(bstr("category"))) {
+ prop = icalproperty_new_categories(bstr("category"));
+ icalcomponent_add_property(vtodo,prop);
+ }
while (prop = icalcomponent_get_first_property(vtodo,
- ICAL_DUE_PROPERTY), prop != NULL) {
+ ICAL_DUE_PROPERTY), prop != NULL) {
icalcomponent_remove_property(vtodo, prop);
icalproperty_free(prop);
}
- icaltime_from_webform(&t, "due");
- icalcomponent_add_property(vtodo,
- icalproperty_new_due(t)
- );
-
+ if (IsEmptyStr(bstr("nodue"))) {
+ if (yesbstr("due_time")) {
+ icaltime_from_webform(&t, "due");
+ }
+ else {
+ icaltime_from_webform_dateonly(&t, "due");
+ }
+ icalcomponent_add_property(vtodo,
+ icalproperty_new_due(t)
+ );
+ }
/** Give this task a UID if it doesn't have one. */
lprintf(9, "Give this task a UID if it doesn't have one.\n");
if (icalcomponent_get_first_property(vtodo,
- ICAL_UID_PROPERTY) == NULL) {
+ ICAL_UID_PROPERTY) == NULL) {
generate_uuid(buf);
icalcomponent_add_property(vtodo,
- icalproperty_new_uid(buf)
- );
+ icalproperty_new_uid(buf)
+ );
}
- /** Increment the sequence ID */
+ /* Increment the sequence ID */
lprintf(9, "Increment the sequence ID\n");
while (prop = icalcomponent_get_first_property(vtodo,
- ICAL_SEQUENCE_PROPERTY), (prop != NULL) ) {
+ ICAL_SEQUENCE_PROPERTY), (prop != NULL) ) {
i = icalproperty_get_sequence(prop);
lprintf(9, "Sequence was %d\n", i);
if (i > sequence) sequence = i;
@@ -697,10 +932,10 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
++sequence;
lprintf(9, "New sequence is %d. Adding...\n", sequence);
icalcomponent_add_property(vtodo,
- icalproperty_new_sequence(sequence)
- );
+ icalproperty_new_sequence(sequence)
+ );
- /**
+ /*
* Encapsulate event into full VCALENDAR component. Clone it first,
* for two reasons: one, it's easier to just free the whole thing
* when we're done instead of unbundling, but more importantly, we
@@ -719,7 +954,7 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
serv_puts(icalcomponent_as_ical_string(encaps));
serv_puts("000");
- /**
+ /*
* Probably not necessary; the server will see the UID
* of the object and delete the old one anyway, but
* just in case...
@@ -732,12 +967,12 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
/**
* If the user clicked 'Delete' then explicitly delete the message.
*/
- if (!IsEmptyStr(bstr("delete_button"))) {
+ if (havebstr("delete_button")) {
delete_existing = 1;
}
if ( (delete_existing) && (msgnum > 0L) ) {
- serv_printf("DELE %ld", atol(bstr("msgnum")));
+ serv_printf("DELE %ld", lbstr("msgnum"));
serv_getln(buf, sizeof buf);
}
@@ -745,30 +980,74 @@ void save_individual_task(icalcomponent *supplied_vtodo, long msgnum) {
icalcomponent_free(vtodo);
}
- /** Go back to the task list */
- readloop("readfwd");
+ /* Go back to wherever we came from */
+ if (ibstr("return_to_summary") == 1) {
+ summary();
+ }
+ else {
+ readloop(readfwd);
+ }
}
-/**
- * \brief generic item handler
- * Code common to all display handlers. Given a message number and a MIME
+void process_ical_object(long msgnum, int unread,
+ char *from,
+ char *FlatIcal,
+ icalcomponent_kind which_kind,
+ IcalCallbackFunc CallBack,
+ struct calview *calv
+ )
+{
+ icalcomponent *cal, *c;
+
+ cal = icalcomponent_new_from_string(FlatIcal);
+ if (cal != NULL) {
+
+ /* A which_kind of (-1) means just load the whole thing */
+ if (which_kind == (-1)) {
+ CallBack(cal, msgnum, from, unread, calv);
+ }
+
+ /* Otherwise recurse and hunt */
+ else {
+
+ /* Simple components of desired type */
+ if (icalcomponent_isa(cal) == which_kind) {
+ CallBack(cal, msgnum, from, unread, calv);
+ }
+
+ /* Subcomponents of desired type */
+ for (c = icalcomponent_get_first_component(cal, which_kind);
+ (c != 0);
+ c = icalcomponent_get_next_component(cal, which_kind)) {
+ CallBack(c, msgnum, from, unread, calv);
+ }
+
+ }
+
+ icalcomponent_free(cal);
+ }
+}
+
+/*
+ * Code common to all icalendar display handlers. Given a message number and a MIME
* type, we load the message and hunt for that MIME type. If found, we load
* the relevant part, deserialize it into a libical component, filter it for
* the requested object type, and feed it to the specified handler.
- * \param mimetype mimetyp of our object
- * \param which_kind sort of ical type
- * \param msgnum number of the mesage in our db
- * \param callback a funcion \todo
- *
*/
-void display_using_handler(long msgnum,
- char *mimetype,
- icalcomponent_kind which_kind,
- void (*callback)(icalcomponent *, long)
- ) {
- char buf[1024];
+void load_ical_object(long msgnum, int unread,
+ icalcomponent_kind which_kind,
+ IcalCallbackFunc CallBack,
+ struct calview *calv,
+ int RenderAsync
+ )
+{
+ StrBuf *Buf;
+ StrBuf *Data;
+ const char *bptr;
+ int Done = 0;
+ char from[128] = "";
char mime_partnum[256];
char mime_filename[256];
char mime_content_type[256];
@@ -776,157 +1055,198 @@ void display_using_handler(long msgnum,
int mime_length;
char relevant_partnum[256];
char *relevant_source = NULL;
- icalcomponent *cal, *c;
+ int phase = 0; /* 0 = citadel headers, 1 = mime headers, 2 = body */
+ char msg4_content_type[256] = "";
+ char msg4_content_encoding[256] = "";
+ int msg4_content_length = 0;
relevant_partnum[0] = '\0';
- sprintf(buf, "MSG0 %ld|0", msgnum); /* unfortunately we need the mime headers */
- serv_puts(buf);
- serv_getln(buf, sizeof buf);
- if (buf[0] != '1') return;
-
- while (serv_getln(buf, sizeof buf), strcmp(buf, "000")) {
- if (!strncasecmp(buf, "part=", 5)) {
- extract_token(mime_filename, &buf[5], 1, '|', sizeof mime_filename);
- extract_token(mime_partnum, &buf[5], 2, '|', sizeof mime_partnum);
- extract_token(mime_disposition, &buf[5], 3, '|', sizeof mime_disposition);
- extract_token(mime_content_type, &buf[5], 4, '|', sizeof mime_content_type);
- mime_length = extract_int(&buf[5], 5);
-
- if (!strcasecmp(mime_content_type, "text/calendar")) {
- strcpy(relevant_partnum, mime_partnum);
+ serv_printf("MSG4 %ld", msgnum); /* we need the mime headers */
+ Buf = NewStrBuf();
+ StrBuf_ServGetln(Buf);
+ if (GetServerStatus(Buf, NULL) != 1) {
+ FreeStrBuf (&Buf);
+ return;
+ }
+ while (!Done && (StrBuf_ServGetln(Buf)>=0)) {
+ if ( (StrLength(Buf)==3) &&
+ !strcmp(ChrPtr(Buf), "000")) {
+ Done = 1;
+ break;
+ }
+ bptr = ChrPtr(Buf);
+ switch (phase) {
+ case 0:
+ if (!strncasecmp(bptr, "part=", 5)) {
+ extract_token(mime_filename, &bptr[5], 1, '|', sizeof mime_filename);
+ extract_token(mime_partnum, &bptr[5], 2, '|', sizeof mime_partnum);
+ extract_token(mime_disposition, &bptr[5], 3, '|', sizeof mime_disposition);
+ extract_token(mime_content_type, &bptr[5], 4, '|', sizeof mime_content_type);
+ mime_length = extract_int(&bptr[5], 5);
+
+ if ( (!strcasecmp(mime_content_type, "text/calendar"))
+ || (!strcasecmp(mime_content_type, "application/ics"))
+ || (!strcasecmp(mime_content_type, "text/vtodo"))
+ ) {
+ strcpy(relevant_partnum, mime_partnum);
+ }
}
- else if (!strcasecmp(mime_content_type, "text/vtodo")) {
- strcpy(relevant_partnum, mime_partnum);
+ else if (!strncasecmp(bptr, "from=", 4)) {
+ extract_token(from, bptr, 1, '=', sizeof(from));
}
-
- }
- }
-
- if (!IsEmptyStr(relevant_partnum)) {
- relevant_source = load_mimepart(msgnum, relevant_partnum);
- if (relevant_source != NULL) {
-
- cal = icalcomponent_new_from_string(relevant_source);
- if (cal != NULL) {
-
- ical_dezonify(cal);
-
- /** Simple components of desired type */
- if (icalcomponent_isa(cal) == which_kind) {
- callback(cal, msgnum);
+ else if ((phase == 0) && (!strncasecmp(bptr, "text", 4))) {
+ phase = 1;
+ }
+ break;
+ case 1:
+ if (!IsEmptyStr(bptr)) {
+ if (!strncasecmp(bptr, "Content-type: ", 14)) {
+ safestrncpy(msg4_content_type, &bptr[14], sizeof msg4_content_type);
+ striplt(msg4_content_type);
}
-
- /** Subcomponents of desired type */
- for (c = icalcomponent_get_first_component(cal,
- which_kind);
- (c != 0);
- c = icalcomponent_get_next_component(cal,
- which_kind)) {
- callback(c, msgnum);
+ else if (!strncasecmp(bptr, "Content-transfer-encoding: ", 27)) {
+ safestrncpy(msg4_content_encoding, &bptr[27], sizeof msg4_content_encoding);
+ striplt(msg4_content_type);
+ }
+ else if ((!strncasecmp(bptr, "Content-length: ", 16))) {
+ msg4_content_length = atoi(&bptr[16]);
}
- icalcomponent_free(cal);
+ break;
}
- free(relevant_source);
+ else {
+ phase++;
+
+ if ((msg4_content_length > 0)
+ && ( !strcasecmp(msg4_content_encoding, "7bit"))
+ && ((!strcasecmp(mime_content_type, "text/calendar"))
+ || (!strcasecmp(mime_content_type, "application/ics"))
+ || (!strcasecmp(mime_content_type, "text/vtodo"))
+ )
+ )
+ {
+ }
+ }
+ case 2:
+ Data = NewStrBufPlain(NULL, msg4_content_length * 2);
+ if (msg4_content_length > 0) {
+ StrBuf_ServGetBLOBBuffered(Data, msg4_content_length);
+ phase ++;
+ }
+ else {
+ StrBufAppendBuf(Data, Buf, 0);
+ StrBufAppendBufPlain(Data, "\r\n", 1, 0);
+ }
+ case 3:
+ StrBufAppendBuf(Data, Buf, 0);
}
}
+ FreeStrBuf(&Buf);
+
+ /* If MSG4 didn't give us the part we wanted, but we know that we can find it
+ * as one of the other MIME parts, attempt to load it now.
+ */
+ if ((Data == NULL) && (!IsEmptyStr(relevant_partnum))) {
+ Data = load_mimepart(msgnum, relevant_partnum);
+ }
+ if (Data != NULL) {
+ relevant_source = (char*) ChrPtr(Data);
+ process_ical_object(msgnum, unread,
+ from,
+ relevant_source,
+ which_kind,
+ CallBack,
+ calv);
+ FreeStrBuf (&Data);
+ }
+
+ icalmemory_free_ring();
}
-/**
- * \brief display whole calendar
- * \param msgnum number of the mesage in our db
+/*
+ * Display a calendar item
*/
-void display_calendar(long msgnum) {
- display_using_handler(msgnum, "text/calendar",
- ICAL_VEVENT_COMPONENT,
- display_individual_cal);
+void load_calendar_item(message_summary *Msg, int unread, struct calview *c) {
+ load_ical_object(Msg->msgnum, unread, (-1), display_individual_cal, c, 1);
}
-/**
- * \brief display whole taksview
- * \param msgnum number of the mesage in our db
+/*
+ * Display task view
*/
-void display_task(long msgnum) {
- display_using_handler(msgnum, "text/calendar",
- ICAL_VTODO_COMPONENT,
- display_individual_cal);
+void display_task(message_summary *Msg, int unread) {
+ load_ical_object(Msg->msgnum, unread, ICAL_VTODO_COMPONENT, display_individual_cal, NULL, 0);
}
-/**
- * \brief display the editor component for a task
+/*
+ * Display the editor component for a task
*/
void display_edit_task(void) {
long msgnum = 0L;
-
- /** Force change the room if we have to */
- if (!IsEmptyStr(bstr("taskrm"))) {
- gotoroom(bstr("taskrm"));
+
+ /* Force change the room if we have to */
+ if (havebstr("taskrm")) {
+ gotoroom(sbstr("taskrm"));
}
- msgnum = atol(bstr("msgnum"));
+ msgnum = lbstr("msgnum");
if (msgnum > 0L) {
- /** existing task */
- display_using_handler(msgnum, "text/calendar",
- ICAL_VTODO_COMPONENT,
- display_edit_individual_task);
+ /* existing task */
+ load_ical_object(msgnum, 0,
+ ICAL_VTODO_COMPONENT,
+ display_edit_individual_task,
+ NULL, 0
+ );
}
else {
- /** new task */
- display_edit_individual_task(NULL, 0L);
+ /* new task */
+ display_edit_individual_task(NULL, 0L, "", 0, NULL);
}
}
-/**
- *\brief save an edited task
+/*
+ * save an edited task
*/
void save_task(void) {
long msgnum = 0L;
-
- msgnum = atol(bstr("msgnum"));
+ msgnum = lbstr("msgnum");
if (msgnum > 0L) {
- display_using_handler(msgnum, "text/calendar",
- ICAL_VTODO_COMPONENT,
- save_individual_task);
+ load_ical_object(msgnum, 0, ICAL_VTODO_COMPONENT, save_individual_task, NULL, 0);
}
else {
- save_individual_task(NULL, 0L);
+ save_individual_task(NULL, 0L, "", 0, NULL);
}
}
-/**
- * \brief display the editor component for an event
+/*
+ * display the editor component for an event
*/
void display_edit_event(void) {
long msgnum = 0L;
- msgnum = atol(bstr("msgnum"));
+ msgnum = lbstr("msgnum");
if (msgnum > 0L) {
/* existing event */
- display_using_handler(msgnum, "text/calendar",
- ICAL_VEVENT_COMPONENT,
- display_edit_individual_event);
+ load_ical_object(msgnum, 0, ICAL_VEVENT_COMPONENT, display_edit_individual_event, NULL, 0);
}
else {
/* new event */
- display_edit_individual_event(NULL, 0L);
+ display_edit_individual_event(NULL, 0L, "", 0, NULL);
}
}
-/**
- * \brief save an edited event
+/*
+ * save an edited event
*/
void save_event(void) {
long msgnum = 0L;
- msgnum = atol(bstr("msgnum"));
+ msgnum = lbstr("msgnum");
if (msgnum > 0L) {
- display_using_handler(msgnum, "text/calendar",
- ICAL_VEVENT_COMPONENT,
- save_individual_event);
+ load_ical_object(msgnum, 0, (-1), save_individual_event, NULL, 0);
}
else {
- save_individual_event(NULL, 0L);
+ save_individual_event(NULL, 0L, "", 0, NULL);
}
}
@@ -934,15 +1254,16 @@ void save_event(void) {
-/**
- * \brief freebusy display (for client software)
- * \param req dunno. ?????
+/*
+ * Anonymous request of freebusy data for a user
*/
-void do_freebusy(char *req) {
+void do_freebusy(void)
+{ /// TODO: request line const char *req) {
+ const char req[] = "";
char who[SIZ];
char buf[SIZ];
- char *fb;
int len;
+ long lines;
extract_token(who, req, 1, ' ', sizeof who);
if (!strncasecmp(who, "/freebusy/", 10)) {
@@ -952,8 +1273,8 @@ void do_freebusy(char *req) {
len = strlen(who);
if ( (!strcasecmp(&who[len-4], ".vcf"))
- || (!strcasecmp(&who[len-4], ".ifb"))
- || (!strcasecmp(&who[len-4], ".vfb")) ) {
+ || (!strcasecmp(&who[len-4], ".ifb"))
+ || (!strcasecmp(&who[len-4], ".vfb")) ) {
who[len-4] = 0;
}
@@ -962,22 +1283,34 @@ void do_freebusy(char *req) {
serv_getln(buf, sizeof buf);
if (buf[0] != '1') {
- wprintf("HTTP/1.1 404 %s\n", &buf[4]);
+ hprintf("HTTP/1.1 404 %s\n", &buf[4]);
output_headers(0, 0, 0, 0, 0, 0);
- wprintf("Content-Type: text/plain\r\n");
- wprintf("\r\n");
+ hprintf("Content-Type: text/plain\r\n");
wprintf("%s\n", &buf[4]);
+ end_burst();
return;
}
- fb = read_server_text();
- http_transmit_thing(fb, strlen(fb), "text/calendar", 0);
- free(fb);
+ read_server_text(WC->WBuf, &lines);
+ http_transmit_thing("text/calendar", 0);
}
-#endif /* WEBCIT_WITH_CALENDAR_SERVICE */
-
-/*@}*/
+void
+InitModule_CALENDAR
+(void)
+{
+ RegisterPreference("daystart", _("Calendar day view begins at:"), PRF_INT, NULL);
+ RegisterPreference("dayend", _("Calendar day view ends at:"), PRF_INT, NULL);
+ RegisterPreference("weekstart", _("Week starts on:"), PRF_INT, NULL);
+
+ WebcitAddUrlHandler(HKEY("freebusy"), do_freebusy, COOKIEUNNEEDED|ANONYMOUS|FORCE_SESSIONCLOSE);
+ WebcitAddUrlHandler(HKEY("display_edit_task"), display_edit_task, 0);
+ WebcitAddUrlHandler(HKEY("save_task"), save_task, 0);
+ WebcitAddUrlHandler(HKEY("display_edit_event"), display_edit_event, 0);
+ WebcitAddUrlHandler(HKEY("save_event"), save_event, 0);
+ WebcitAddUrlHandler(HKEY("respond_to_request"), respond_to_request, 0);
+ WebcitAddUrlHandler(HKEY("handle_rsvp"), handle_rsvp, 0);
+}
|