* New command 'WIKI history|<pagename>' to list the revision history for a wiki page.
authorArt Cancro <ajc@citadel.org>
Wed, 21 Oct 2009 17:30:28 +0000 (17:30 +0000)
committerArt Cancro <ajc@citadel.org>
Wed, 21 Oct 2009 17:30:28 +0000 (17:30 +0000)
* History format has changed again -- delete any experimental wiki rooms you have created.  The memo field now contains a UUID for each edit, which we will use for identifying revisions because the MIME part numbers will change with each edit.  Also moved the timestamp into the second field position, followed by the username and nodename.  No longer saving the user's Internet email address.

citadel/modules/wiki/serv_wiki.c
citadel/msgbase.c
webcit/roomops.c

index 522775c4b95ad5a087a3a769f60173fe20f2671a..1a0db44796dbc825fe23d04bfc3d8e04d0dc5260 100644 (file)
@@ -252,12 +252,16 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) {
                ptr = bmstrcasestr(history_msg->cm_fields['M'], prefixed_boundary);
                if (ptr != NULL) {
                        char *the_rest_of_it = strdup(ptr);
+                       char uuid[32];
                        char memo[512];
                        char encoded_memo[768];
-                       snprintf(memo, sizeof memo, "%s|%s|%ld", 
+                       generate_uuid(uuid);
+                       snprintf(memo, sizeof memo, "%s|%ld|%s|%s", 
+                               uuid,
+                               time(NULL),
                                CCC->user.fullname,
-                               CCC->cs_inet_email,
-                               time(NULL)
+                               config.c_nodename
+                               /* no longer logging CCC->cs_inet_email */
                        );
                        CtdlEncodeBase64(encoded_memo, memo, strlen(memo), 0);
                        sprintf(ptr, "--%s\n"
@@ -291,14 +295,89 @@ int wiki_upload_beforesave(struct CtdlMessage *msg) {
 }
 
 
+/*
+ * MIME Parser callback for wiki_history()
+ *
+ * The "filename" field will contain a memo field.  All we have to do is decode
+ * the base64 and output it.  The data is already in a delimited format suitable
+ * for our client protocol.
+ */
+void wiki_history_callback(char *name, char *filename, char *partnum, char *disp,
+                  void *content, char *cbtype, char *cbcharset, size_t length,
+                  char *encoding, char *cbid, void *cbuserdata)
+{
+       char memo[1024];
+
+       CtdlDecodeBase64(memo, filename, strlen(filename));
+       cprintf("%s\n", memo);
+}
+
+
+/*
+ * Fetch a list of revisions for a particular wiki page
+ */
+void wiki_history(char *pagename) {
+       int r;
+       char history_page_name[270];
+       long msgnum;
+       struct CtdlMessage *msg;
+
+       r = CtdlDoIHavePermissionToReadMessagesInThisRoom();
+       if (r != om_ok) {
+               if (r == om_not_logged_in) {
+                       cprintf("%d Not logged in.\n", ERROR + NOT_LOGGED_IN);
+               }
+               else {
+                       cprintf("%d An unknown error has occurred.\n", ERROR);
+               }
+               return;
+       }
+
+       snprintf(history_page_name, sizeof history_page_name, "%s_HISTORY_", pagename);
+       msgnum = locate_message_by_euid(history_page_name, &CC->room);
+       if (msgnum > 0L) {
+               msg = CtdlFetchMessage(msgnum, 1);
+       }
+       else {
+               msg = NULL;
+       }
+
+       if ((msg != NULL) && (msg->cm_fields['M'] == NULL)) {
+               CtdlFreeMessage(msg);
+               msg = NULL;
+       }
+
+       if (msg == NULL) {
+               cprintf("%d Revision history for '%s' was not found.\n", ERROR+MESSAGE_NOT_FOUND, pagename);
+               return;
+       }
+
+       
+       cprintf("%d Revision history for '%s'\n", LISTING_FOLLOWS, pagename);
+       mime_parser(msg->cm_fields['M'], NULL, *wiki_history_callback, NULL, NULL, NULL, 0);
+       cprintf("000\n");
+
+       CtdlFreeMessage(msg);
+       return;
+}
+
 
 /*
  * commands related to wiki management
  */
 void cmd_wiki(char *argbuf) {
-       cprintf("%d FIXME not finished\n", ERROR);
+       char subcmd[32];
+       char pagename[256];
+
+       extract_token(subcmd, argbuf, 0, '|', sizeof subcmd);
+
+       if (!strcasecmp(subcmd, "history")) {
+               extract_token(pagename, argbuf, 1, '|', sizeof subcmd);
+               wiki_history(pagename);
+               return;
+       }
 
-       /* mime_parser(mptr, NULL, *mime_download, NULL, NULL, NULL, 0); */
+       cprintf("%d Invalid subcommand\n", ERROR + CMD_NOT_SUPPORTED);
 }
 
 
index c90ef0e2c28c2bd0392da2e4d1c586ec46c6a6af..1e1b3a198388e7176050badd4265a9a2def1bafd 100644 (file)
@@ -2,7 +2,22 @@
  * $Id$
  *
  * Implements the message store.
+ * 
+ * Copyright (c) 1987-2009 by the citadel.org team
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 3 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
  *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
 #include "sysdep.h"
index 99806edb1cb30617801efac01f8616414f9cfd10..456b19ce657c104fcc68a0f178bc8bdb0185a6a8 100644 (file)
@@ -44,7 +44,7 @@ int is_view_allowed_as_default(int which_view)
                case VIEW_CALENDAR:     return(1);
                case VIEW_TASKS:        return(1);
                case VIEW_NOTES:        return(1);
-               case VIEW_WIKI:         return(0);      /* because it isn't finished yet */
+               case VIEW_WIKI:         return(1);
                case VIEW_CALBRIEF:     return(0);
                case VIEW_JOURNAL:      return(0);
                default:                return(0);      /* should never get here */