- added versioning to Wiki

git-svn-id: https://svn.berlios.de/svnroot/repos/yacy/trunk@3327 6c8d7289-2bf4-0310-a012-ef5d649a1542
pull/1/head
karlchenofhell 18 years ago
parent 10ebcb5e1e
commit f2e6f19b90

@ -19,7 +19,12 @@
last edited by #[author]# | change date #[date]# | <a href="Wiki.html?page=#[pagename]#&amp;edit=Edit">Edit</a> #(access)#(only granted to admin)::#(/access)# last edited by #[author]# | change date #[date]# | <a href="Wiki.html?page=#[pagename]#&amp;edit=Edit">Edit</a> #(access)#(only granted to admin)::#(/access)#
</p> </p>
</div> </div>
<p class="Navigation"><a href="Wiki.html">Start Page</a> - <a href="Wiki.html?index=Index">Index</a> - #(access)#<a href="Wiki.html?access=all">Grant Write Access to Everybody</a>::<a href="Wiki.html?access=admin">Grant Write Access to Admin only</a>#(/access)#</p> <p class="Navigation">
<a href="Wiki.html">Start Page</a> -
<a href="Wiki.html?index=Index">Index</a> -
<a href="Wiki.html?page=#[pagename]#&amp;diff=">Versions</a> -
#(access)#<a href="Wiki.html?access=all">Grant Write Access to Everybody</a>::<a href="Wiki.html?access=admin">Grant Write Access to Admin only</a>#(/access)#
</p>
:: ::
<!-- 1: edit --> <!-- 1: edit -->
<form action="Wiki.html" method="post" enctype="multipart/form-data" accept-charset="UTF-8"> <form action="Wiki.html" method="post" enctype="multipart/form-data" accept-charset="UTF-8">
@ -106,6 +111,39 @@
<p class="Navigation"> <p class="Navigation">
<a href="Wiki.html">Start Page</a> <a href="Wiki.html">Start Page</a>
</p> </p>
::
<!-- 4: Diff -->
#(error)#<!-- no error -->
<form method="get" action="Wiki.html">
<fieldset><legend>Select versions of page '#[page]#</legend>
<input type="hidden" name="page" value="#[page]#" />
<dl>
<dt><label for="old">Compare version from</label>:</dt>
<dd>
<select id="old" name="old">#{versions}#
<option value="#[date]#"#(oldselected)#:: selected="selected"#(/oldselected)#>#[fdate]#</option>#{/versions}#
</select>
</dd>
<dt><label for="new">with version from</label>:</dt>
<dd>
<select id="new" name="new">
<optgroup label="current"><option value="#[curdate]#"#(curselected)#:: selected="selected"#(/curselected)#>#[curfdate]#</option></optgroup>#{versions}#
<option value="#[date]#"#(newselected)#:: selected="selected"#(/newselected)#>#[fdate]#</option>#{/versions}#
</select>
</dd>
<dt><input type="submit" name="diff" value="Compare" /></dt>
</dl>
</fieldset>
</form>
::<!-- IO error -->
<p class="error">IO Error reading wiki database: #[message]#</p>
::<!-- no entries available for #[name]# -->
#(/error)#
#[diff]#
<p class="Navigation">
<a href="Wiki.html">Start Page</a> -
<a href="Wiki.html?page=#[page]#">Return to #[page]#</a>
</p>
#(/mode)# #(/mode)#
<p>Changes will be published as announcement on YaCyNews</p> <p>Changes will be published as announcement on YaCyNews</p>

@ -53,6 +53,7 @@ import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import de.anomic.data.Diff;
import de.anomic.data.wikiBoard; import de.anomic.data.wikiBoard;
import de.anomic.http.httpHeader; import de.anomic.http.httpHeader;
import de.anomic.plasma.plasmaSwitchboard; import de.anomic.plasma.plasmaSwitchboard;
@ -155,7 +156,7 @@ public class Wiki {
prop.put("mode_author", author); prop.put("mode_author", author);
prop.put("mode_date", dateString(new Date())); prop.put("mode_date", dateString(new Date()));
prop.putWiki("mode_page", post.get("content", "")); prop.putWiki("mode_page", post.get("content", ""));
prop.put("mode_page-code", post.get("content", "").replaceAll("<","&lt;").replaceAll(">","&gt;")); prop.put("mode_page-code", post.get("content", ""));
} }
//end contrib of [MN] //end contrib of [MN]
@ -184,6 +185,68 @@ public class Wiki {
prop.put("mode_pagename", pagename); prop.put("mode_pagename", pagename);
} }
else if (post.containsKey("diff")) {
prop.put("mode", 4);
prop.put("mode_page", pagename);
prop.put("mode_error_page", pagename);
try {
Iterator it = switchboard.wikiDB.keysBkp(true);
wikiBoard.entry entry;
wikiBoard.entry oentry = null;
wikiBoard.entry nentry = null;
int count = 0;
boolean oldselected = false, newselected = false;
while (it.hasNext()) {
entry = switchboard.wikiDB.readBkp((String)it.next());
prop.put("mode_error_versions_" + count + "_date", wikiBoard.dateString(entry.date()));
prop.put("mode_error_versions_" + count + "_fdate", dateString(entry.date()));
if (wikiBoard.dateString(entry.date()).equals(post.get("old", null))) {
prop.put("mode_error_versions_" + count + "_oldselected", 1);
oentry = entry;
oldselected = true;
} else if (wikiBoard.dateString(entry.date()).equals(post.get("new", null))) {
prop.put("mode_error_versions_" + count + "_newselected", 1);
nentry = entry;
newselected = true;
}
count++;
}
count--; // don't show current version
if (!oldselected) // select latest old entry
prop.put("mode_error_versions_" + (count - 1) + "_oldselected", 1);
if (!newselected) // select latest new entry (== current)
prop.put("mode_error_curselected", 1);
if (count == 0) {
prop.put("mode_error", 2); // no entries found
} else {
prop.put("mode_error_versions", count);
}
entry = switchboard.wikiDB.read(pagename);
if (entry != null) {
prop.put("mode_error_curdate", wikiBoard.dateString(entry.date()));
prop.put("mode_error_curfdate", dateString(entry.date()));
}
if (nentry == null) nentry = entry;
if (post.get("diff", "").length() > 0 && oentry != null && nentry != null) {
// TODO: split into paragraphs and compare them with the same diff-algo
Diff diff = new Diff(
new String(oentry.page(), "UTF-8"),
new String(nentry.page(), "UTF-8"), 5);
prop.putASIS("mode_diff", Diff.toHTML(new Diff[] { diff }));
} else {
prop.put("mode_diff", "");
}
} catch (IOException e) {
prop.put("mode_error", 1); //IO Error reading Wiki
prop.put("mode_error_message", e.getMessage());
}
}
else { else {
// show page // show page
prop.put("mode", 0); //viewing prop.put("mode", 0); //viewing

@ -34,7 +34,7 @@
/* --------------- global elements -------------------------- */ /* --------------- global elements -------------------------- */
* { * {
font-family:Helvetica, Arial, sans-serif; font-family:/*Helvetica, Arial, */sans-serif;
} }
body { body {
@ -165,6 +165,17 @@ legend {
padding: 8px; padding: 8px;
} }
.diff {
margin: 10px 5px;
border: 1px dashed #722;
padding: .5em;
font-family: monospace;
}
.diff .unchanged { font-family: monospace; }
.diff .added { font-family: monospace; }
.diff .deleted { font-family: monospace; text-decoration: line-through; }
.imgtable { .imgtable {
margin: 1px; margin: 1px;
padding: 1px; padding: 1px;

@ -54,6 +54,11 @@ a.bookmarkAction { color: #999999; }
.Navigation a { color: #555; } .Navigation a { color: #555; }
.Navigation a:hover { color: #777; } .Navigation a:hover { color: #777; }
.diff { background-color: #171717; }
.diff .unchanged { color: #666; }
.diff .added { color: #0A0; background-color: #053005; }
.diff .deleted { color: #B00; background-color: #390505; }
/* in Status.html */ /* in Status.html */
.ProgressBar { border: 1px solid #777; } .ProgressBar { border: 1px solid #777; }
.ProgressBarFill { background-color: #944; } .ProgressBarFill { background-color: #944; }

@ -132,6 +132,10 @@ a.bookmarkAction {
border-left: 2px solid black; border-left: 2px solid black;
} }
.diff { background-color: #E8E8EE; }
.diff .unchanged { color: #333; }
.diff .added { color: #090; background-color: #B5F0B5; }
.diff .deleted { color: #B00; background-color: #F9B5B5; }
/* in Status.html */ /* in Status.html */

@ -136,6 +136,10 @@ a.bookmarkAction {
border-left: 2px solid black; border-left: 2px solid black;
} }
.diff { background-color: #E8E8E8; }
.diff .unchanged { color: #333; }
.diff .added { color: #090; background-color: #B5F0B5; }
.diff .deleted { color: #B00; background-color: #F9B5B5; }
/* in Status.html */ /* in Status.html */

@ -133,6 +133,10 @@ a.bookmarkAction {
border-left: 2px solid black; border-left: 2px solid black;
} }
.diff { background-color: #E5FFC5; }
.diff .unchanged { color: #333; }
.diff .added { color: #090; background-color: #B5F0B5; }
.diff .deleted { color: #B00; background-color: #F9B5B5; }
/* in Status.html */ /* in Status.html */

@ -144,6 +144,10 @@ a.bookmarkAction {
border-left: 2px solid black; border-left: 2px solid black;
} }
.diff { background-color: #171717; }
.diff .unchanged { color: #666; }
.diff .added { color: #0A0; background-color: #053005; }
.diff .deleted { color: #B00; background-color: #390505; }
/* in Status.html */ /* in Status.html */

@ -143,7 +143,7 @@ public class Diff {
if (!matrix[yy + i][xx + i]) break; if (!matrix[yy + i][xx + i]) break;
if (i <= minLength && yy + i < matrix.length && xx + i < matrix[yy].length) { if (i <= minLength && yy + i < matrix.length && xx + i < matrix[yy].length) {
// vorzeitig abgebrochen => zuwenige chars in Diagonale => weitersuchen // vorzeitig abgebrochen => zuwenige chars in Diagonale => weitersuchen
break; continue;
} else { } else {
return new int[] { rx, ry, i }; return new int[] { rx, ry, i };
} }
@ -170,6 +170,13 @@ public class Diff {
*/ */
public Part[] getParts() { return (Part[])this.parts.toArray(new Part[this.parts.size()]); } public Part[] getParts() { return (Part[])this.parts.toArray(new Part[this.parts.size()]); }
public String toString() {
StringBuffer sb = new StringBuffer(this.parts.size() * 20);
for (int j=0; j<this.parts.size(); j++)
sb.append(((Part)this.parts.get(j)).toString()).append("\n");
return sb.toString();
}
/** /**
* This class represents a part of the diff, meaning one operation * This class represents a part of the diff, meaning one operation
* (or one line of a "normal" diff) * (or one line of a "normal" diff)
@ -220,4 +227,25 @@ public class Diff {
(this.action == ADDED) ? "+" : "-") + " " + getString(); (this.action == ADDED) ? "+" : "-") + " " + getString();
} }
} }
public static String toHTML(Diff[] diffs) {
StringBuffer sb = new StringBuffer(diffs.length * 60);
Diff.Part[] ps;
for (int i=0; i<diffs.length; i++) {
sb.append("<p class=\"diff\">\n");
ps = diffs[i].getParts();
for (int j=0; j<ps.length; j++) {
sb.append("<span\nclass=\"");
switch (ps[j].getAction()) {
case Diff.Part.UNCHANGED: sb.append("unchanged"); break;
case Diff.Part.ADDED: sb.append("added"); break;
case Diff.Part.DELETED: sb.append("deleted"); break;
}
sb.append("\">").append(wikiCode.replaceXMLEntities(ps[j].getString()).replaceAll("\n", "<br />"));
sb.append("</span>");
}
sb.append("</p>");
}
return sb.toString();
}
} }

@ -1,42 +1,42 @@
// wikiBoard.java //wikiBoard.java
// ------------------------------------- //-------------------------------------
// (C) by Michael Peter Christen; mc@anomic.de //(C) by Michael Peter Christen; mc@anomic.de
// first published on http://www.anomic.de //first published on http://www.anomic.de
// Frankfurt, Germany, 2004 //Frankfurt, Germany, 2004
// last major change: 20.07.2004 //last major change: 20.07.2004
//
// This program is free software; you can redistribute it and/or modify //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 //it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or //the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version. //(at your option) any later version.
//
// This program is distributed in the hope that it will be useful, //This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of //but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the //MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details. //GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License //You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software //along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA //Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
//
// Using this software in any meaning (reading, learning, copying, compiling, //Using this software in any meaning (reading, learning, copying, compiling,
// running) means that you agree that the Author(s) is (are) not responsible //running) means that you agree that the Author(s) is (are) not responsible
// for cost, loss of data or any harm that may be caused directly or indirectly //for cost, loss of data or any harm that may be caused directly or indirectly
// by usage of this softare or this documentation. The usage of this software //by usage of this softare or this documentation. The usage of this software
// is on your own risk. The installation and usage (starting/running) of this //is on your own risk. The installation and usage (starting/running) of this
// software may allow other people or application to access your computer and //software may allow other people or application to access your computer and
// any attached devices and is highly dependent on the configuration of the //any attached devices and is highly dependent on the configuration of the
// software which must be done by the user of the software; the author(s) is //software which must be done by the user of the software; the author(s) is
// (are) also not responsible for proper configuration and usage of the //(are) also not responsible for proper configuration and usage of the
// software, even if provoked by documentation provided together with //software, even if provoked by documentation provided together with
// the software. //the software.
//
// Any changes to this file according to the GPL as documented in the file //Any changes to this file according to the GPL as documented in the file
// gpl.txt aside this file in the shipment you received can be done to the //gpl.txt aside this file in the shipment you received can be done to the
// lines that follows this copyright notice here, but changes must not be //lines that follows this copyright notice here, but changes must not be
// done inside the copyright notive above. A re-distribution must contain //done inside the copyright notive above. A re-distribution must contain
// the intact and unchanged copyright notice. //the intact and unchanged copyright notice.
// Contributions and changes to the program code must be marked as such. //Contributions and changes to the program code must be marked as such.
package de.anomic.data; package de.anomic.data;
@ -119,7 +119,7 @@ public class wikiBoard {
return dateString(new GregorianCalendar(GMTTimeZone).getTime()); return dateString(new GregorianCalendar(GMTTimeZone).getTime());
} }
private static String dateString(Date date) { public static String dateString(Date date) {
return SimpleFormatter.format(date); return SimpleFormatter.format(date);
} }
@ -317,6 +317,10 @@ public class wikiBoard {
} }
} }
public entry readBkp(String key) {
return read(key, bkpbase);
}
/* /*
public boolean has(String key) { public boolean has(String key) {
try { try {
@ -331,4 +335,7 @@ public class wikiBoard {
return datbase.keys(up, false); return datbase.keys(up, false);
} }
public Iterator keysBkp(boolean up) throws IOException {
return bkpbase.keys(up, false);
}
} }

@ -172,6 +172,32 @@ public class wikiCode {
return text; return text;
} }
public static String deReplaceHTML(String text) {
text = deReplaceHTMLEntities(text);
text = deReplaceXMLEntities(text);
return text;
}
public static String deReplaceHTMLEntities(String text) {
return deReplace(text, htmlentities);
}
public static String deReplaceXMLEntities(String text) {
return deReplace(text, xmlentities);
}
public static String deReplace(String text, String[] entities) {
if (text == null) return null;
for (int i=entities.length-1; i>0; i-=2) {
int p = 0;
while ((p = text.indexOf(entities[i])) >= 0) {
text = text.substring(0, p) + entities[i - 1] + text.substring(p + entities[i].length());
p += entities[i - 1].length();
}
}
return text;
}
//This array contains codes (see http://mindprod.com/jgloss/unicode.html for details) //This array contains codes (see http://mindprod.com/jgloss/unicode.html for details)
//that will be replaced. To add new codes or patterns, just put them at the end //that will be replaced. To add new codes or patterns, just put them at the end
//of the list. Codes or patterns in this list can not be escaped with [= or <pre> //of the list. Codes or patterns in this list can not be escaped with [= or <pre>

Loading…
Cancel
Save