diff --git a/htroot/Blog.html b/htroot/Blog.html
new file mode 100644
index 000000000..ca879e716
--- /dev/null
+++ b/htroot/Blog.html
@@ -0,0 +1,61 @@
+
+
+
+YaCy '#[clientname]#': Blog
+#%env/templates/metas.template%#
+
+
+#%env/templates/header.template%#
+#(mode)#
+
+
+#{entries}#
+
+
+#[subject]# #[page]# | |
+
+
+
+#{/entries}#
+#(moreentries)#::show more entries...#(/moreentries)#
+
+#(admin)#::new entry - #(/admin)#Blog-Home
+::
+
+
+::
+
+Preview
+No changes have been submitted so far!
+
+
+#[subject]# #[page]# | |
+
+
+
+::
+
+Access denied
+To edit or create blog-entries you need to be logged in as Admin or User that has Blog rights.
+#(/mode)#
+#%env/templates/footer.template%#
+
+
diff --git a/htroot/Blog.java b/htroot/Blog.java
new file mode 100644
index 000000000..942429273
--- /dev/null
+++ b/htroot/Blog.java
@@ -0,0 +1,164 @@
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Iterator;
+
+import de.anomic.data.userDB;
+import de.anomic.data.blogBoard;
+import de.anomic.data.wikiCode;
+import de.anomic.http.httpHeader;
+import de.anomic.plasma.plasmaSwitchboard;
+import de.anomic.server.serverObjects;
+import de.anomic.server.serverSwitch;
+
+public class Blog {
+
+ private static SimpleDateFormat SimpleFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
+// TODO: make userdefined date/time-strings (localisation)
+
+ public static String dateString(Date date) {
+ return SimpleFormatter.format(date);
+ }
+
+ public static serverObjects respond(httpHeader header, serverObjects post, serverSwitch env) {
+ plasmaSwitchboard switchboard = (plasmaSwitchboard) env;
+ serverObjects prop = new serverObjects();
+
+ boolean hasRights = switchboard.verifyAuthentication(header, true);
+ if(!hasRights){
+ userDB.Entry userentry = switchboard.userDB.proxyAuth((String)header.get("Authorization", "xxxxxx"));
+ if(userentry != null && userentry.hasBlogRight()){
+ hasRights=true;
+ }
+ }
+
+ if(hasRights) prop.put("mode_admin",1);
+ else prop.put("mode_admin",0);
+
+ if (post == null) {
+ post = new serverObjects();
+ post.put("page", "blog_default");
+ }
+
+ String pagename = post.get("page", "blog_default");
+ String ip = post.get("CLIENTIP", "127.0.0.1");
+ String author = post.get("author", "anonymous");
+ if (author.equals("anonymous")) {
+ author = switchboard.blogDB.guessAuthor(ip);
+ if (author == null) {
+ if (de.anomic.yacy.yacyCore.seedDB.mySeed == null)
+ author = "anonymous";
+ else
+ author = de.anomic.yacy.yacyCore.seedDB.mySeed.get("Name", "anonymous");
+ }
+ }
+
+ if (post.containsKey("submit") && (hasRights)) {
+ // store a new/edited blog-entry
+ byte[] content;
+ try {
+ content = post.get("content", "").getBytes("UTF-8");
+ } catch (UnsupportedEncodingException e) {
+ content = post.get("content", "").getBytes();
+ }
+
+ //set name for new entry
+ if(pagename.equals("blog_default"))
+ pagename = String.valueOf(System.currentTimeMillis());
+
+ try {
+ switchboard.blogDB.write(switchboard.blogDB.newEntry(pagename, post.get("subject",""), author, ip, content));
+ } catch (IOException e) {}
+ }
+
+ blogBoard.entry page = switchboard.blogDB.read(pagename);
+
+ if (post.containsKey("edit")) {
+ //edit an entry
+ if(hasRights) {
+ try {
+ prop.put("mode", 1); //edit
+ prop.put("mode_author", author);
+ prop.put("mode_pageid", page.key());
+ prop.put("mode_subject", page.subject());
+ prop.put("mode_page-code", new String(page.page(), "UTF-8").replaceAll("<","<").replaceAll(">",">"));
+ } catch (UnsupportedEncodingException e) {}
+ }
+ else {
+ prop.put("mode",3); //access denied (no rights)
+ }
+ }
+ else if(post.containsKey("preview")) {
+ //preview the page
+ if(hasRights) {
+ wikiCode wikiTransformer=new wikiCode(switchboard);
+ prop.put("mode", 2);//preview
+ prop.put("mode_pageid", pagename);
+ prop.put("mode_author", author);
+ prop.put("mode_subject", post.get("subject",""));
+ prop.put("mode_date", dateString(new Date()));
+ prop.put("mode_page", wikiTransformer.transform(post.get("content", "")));
+ prop.put("mode_page-code", post.get("content", "").replaceAll("<","<").replaceAll(">",">"));
+ }
+ else prop.put("mode",3); //access denied (no rights)
+ }
+ else {
+ wikiCode wikiTransformer=new wikiCode(switchboard);
+ // show blog-entry/entries
+ prop.put("mode", 0); //viewing
+ if(pagename.equals("blog_default")) {
+ //index all entries
+ try {
+ Iterator i = switchboard.blogDB.keys(false);
+ String pageid;
+ blogBoard.entry entry;
+ int count = 0; //counts how many entries are shown to the user
+ int start = post.getInt("start",0); //indicates from where entries should be shown
+ int num = post.getInt("num",20); //indicates how many entries should be shown
+ int nextstart = start+num; //indicates the starting offset for next results
+ while(i.hasNext()) {
+ if(count >= num && num > 0)
+ break;
+ pageid = (String) i.next();
+ if(0 < start--)
+ continue;
+ entry = switchboard.blogDB.read(pageid);
+ prop.put("mode_entries_"+count+"_pageid",entry.key());
+ prop.put("mode_entries_"+count+"_subject", entry.subject());
+ prop.put("mode_entries_"+count+"_author", entry.author());
+ prop.put("mode_entries_"+count+"_date", dateString(entry.date()));
+ prop.put("mode_entries_"+count+"_page", wikiTransformer.transform(entry.page()));
+ if(hasRights) {
+ prop.put("mode_entries_"+count+"_admin", 1);
+ prop.put("mode_entries_"+count+"_admin_pageid",entry.key());
+ }
+ else prop.put("mode_entries_"+count+"_admin", 0);
+ ++count;
+ }
+ prop.put("mode_entries",count);
+ if(i.hasNext()) {
+ prop.put("mode_moreentries",1); //more entries are availible
+ prop.put("mode_moreentries_start",nextstart);
+ prop.put("mode_moreentries_num",num);
+ }
+ else prop.put("moreentries",0);
+ } catch (IOException e) {
+
+ }
+ }
+ else {
+ //only show 1 entry
+ prop.put("mode_entries",1);
+ prop.put("mode_entries_0_pageid", page.key());
+ prop.put("mode_entries_0_subject", page.subject());
+ prop.put("mode_entries_0_author", page.author());
+ prop.put("mode_entries_0_date", dateString(page.date()));
+ prop.put("mode_entries_0_page", wikiTransformer.transform(page.page()));
+ }
+ }
+
+ // return rewrite properties
+ return prop;
+ }
+}
diff --git a/htroot/PerformanceMemory_p.html b/htroot/PerformanceMemory_p.html
index 5437fdead..85d80f993 100644
--- a/htroot/PerformanceMemory_p.html
+++ b/htroot/PerformanceMemory_p.html
@@ -238,6 +238,23 @@ This cache is divided in two parts, one for the wiki database and one for its ba
Increasing this cache may speed up access to the wiki pages.
+
+Blog |
+#[chunkBlog]# |
+#[slreqBlog]# |
+#[slempBlog]# |
+#[slhigBlog]# |
+#[slmedBlog]# |
+#[sllowBlog]# |
+#[usedBlog]# |
+ |
+#[dfltBlog]# |
+#[goodBlog]# |
+#[bestBlog]# |
+The YaCy-Blog uses a database to store its entries.
+Increasing this cache may speed up access to the Blog. |
+
+
News |
#[chunkNews]# |
diff --git a/htroot/PerformanceMemory_p.java b/htroot/PerformanceMemory_p.java
index b03a73534..a832108df 100644
--- a/htroot/PerformanceMemory_p.java
+++ b/htroot/PerformanceMemory_p.java
@@ -87,6 +87,7 @@ public class PerformanceMemory_p {
env.setConfig("ramCacheDHT", Long.parseLong(post.get("ramCacheDHT", "0")) * KB);
env.setConfig("ramCacheMessage", Long.parseLong(post.get("ramCacheMessage", "0")) * KB);
env.setConfig("ramCacheWiki", Long.parseLong(post.get("ramCacheWiki", "0")) * KB);
+ env.setConfig("ramCacheBlog", Long.parseLong(post.get("ramCacheBlog", "0")) * KB);
env.setConfig("ramCacheNews", Long.parseLong(post.get("ramCacheNews", "0")) * KB);
env.setConfig("ramCacheRobots", Long.parseLong(post.get("ramCacheRobots", "0")) * KB);
env.setConfig("ramCacheProfiles", Long.parseLong(post.get("ramCacheProfiles", "0")) * KB);
@@ -100,6 +101,7 @@ public class PerformanceMemory_p {
env.setConfig("ramCacheDHT", Long.parseLong((String) defaultSettings.get("ramCacheDHT")));
env.setConfig("ramCacheMessage", Long.parseLong((String) defaultSettings.get("ramCacheMessage")));
env.setConfig("ramCacheWiki", Long.parseLong((String) defaultSettings.get("ramCacheWiki")));
+ env.setConfig("ramCacheWiki", Long.parseLong((String) defaultSettings.get("ramCacheBlog")));
env.setConfig("ramCacheNews", Long.parseLong((String) defaultSettings.get("ramCacheNews")));
env.setConfig("ramCacheRobots", Long.parseLong((String) defaultSettings.get("ramCacheRobots")));
env.setConfig("ramCacheProfiles", Long.parseLong((String) defaultSettings.get("ramCacheProfiles")));
@@ -192,6 +194,11 @@ public class PerformanceMemory_p {
slt = sb.wikiDB.dbCacheFillStatus();
putprop(prop, env, "Wiki", set);
+ req = sb.blogDB.size();
+ chk = sb.blogDB.dbCacheChunkSize();
+ slt = sb.blogDB.dbCacheFillStatus();
+ putprop(prop, env, "Blog", set);
+
req = yacyCore.newsPool.dbSize();
chk = yacyCore.newsPool.dbCacheChunkSize();
slt = yacyCore.newsPool.dbCacheFillStatus();
diff --git a/htroot/Wiki.java b/htroot/Wiki.java
index 20d7b8651..c3d69db78 100644
--- a/htroot/Wiki.java
+++ b/htroot/Wiki.java
@@ -85,7 +85,7 @@ public class Wiki {
String ip = post.get("CLIENTIP", "127.0.0.1");
String author = post.get("author", "anonymous");
if (author.equals("anonymous")) {
- author = switchboard.wikiDB.guessAuthor(ip);
+ author = wikiBoard.guessAuthor(ip);
if (author == null) {
if (de.anomic.yacy.yacyCore.seedDB.mySeed == null) author = "anonymous";
else author = de.anomic.yacy.yacyCore.seedDB.mySeed.get("Name", "anonymous");
diff --git a/source/de/anomic/data/blogBoard.java b/source/de/anomic/data/blogBoard.java
new file mode 100644
index 000000000..584af8287
--- /dev/null
+++ b/source/de/anomic/data/blogBoard.java
@@ -0,0 +1,229 @@
+// wikiBoard.java
+// -------------------------------------
+// (C) by Michael Peter Christen; mc@anomic.de
+// first published on http://www.anomic.de
+// Frankfurt, Germany, 2004
+// last major change: 20.07.2004
+//
+// 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 2 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
+//
+// Using this software in any meaning (reading, learning, copying, compiling,
+// 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
+// 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
+// software may allow other people or application to access your computer and
+// 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
+// (are) also not responsible for proper configuration and usage of the
+// software, even if provoked by documentation provided together with
+// the software.
+//
+// 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
+// lines that follows this copyright notice here, but changes must not be
+// done inside the copyright notive above. A re-distribution must contain
+// the intact and unchanged copyright notice.
+// Contributions and changes to the program code must be marked as such.
+
+// Contains contributions from Jan Sandbrink [JS]
+
+package de.anomic.data;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.TimeZone;
+
+import de.anomic.kelondro.kelondroBase64Order;
+import de.anomic.kelondro.kelondroDyn;
+import de.anomic.kelondro.kelondroMap;
+
+public class blogBoard {
+
+ public static final int keyLength = 64;
+ private static final String dateFormat = "yyyyMMddHHmmss";
+ private static final int recordSize = 512;
+
+ private static TimeZone GMTTimeZone = TimeZone.getTimeZone("PST");
+ private static SimpleDateFormat SimpleFormatter = new SimpleDateFormat(dateFormat);
+
+ private kelondroMap datbase = null;
+
+ public blogBoard(File actpath, int bufferkb) {
+ new File(actpath.getParent()).mkdir();
+ if (datbase == null) {
+ if (actpath.exists()) try {
+ datbase = new kelondroMap(new kelondroDyn(actpath, bufferkb / 2 * 0x40, '_'));
+ } catch (IOException e) {
+ datbase = new kelondroMap(new kelondroDyn(actpath, bufferkb / 2 * 0x400, keyLength, recordSize, '_', true));
+ } else {
+ datbase = new kelondroMap(new kelondroDyn(actpath, bufferkb / 2 * 0x400, keyLength, recordSize, '_', true));
+ }
+ }
+ }
+
+ public int size() {
+ return datbase.size();
+ }
+
+ public int[] dbCacheChunkSize() {
+ return datbase.cacheChunkSize();
+ }
+
+ public int[] dbCacheFillStatus() {
+ return datbase.cacheFillStatus();
+ }
+
+ public void close() {
+ try {datbase.close();} catch (IOException e) {}
+ }
+
+ private static String dateString() {
+ return dateString(new GregorianCalendar(GMTTimeZone).getTime());
+ }
+
+ private static String dateString(Date date) {
+ return SimpleFormatter.format(date);
+ }
+
+ private static String normalize(String key) {
+ if (key == null) return "null";
+ return key.trim().toLowerCase();
+ }
+
+ public static String webalize(String key) {
+ if (key == null) return "null";
+ key = key.trim().toLowerCase();
+ int p;
+ while ((p = key.indexOf(" ")) >= 0)
+ key = key.substring(0, p) + "%20" + key.substring(p +1);
+ return key;
+ }
+
+ public String guessAuthor(String ip) {
+ return wikiBoard.guessAuthor(ip);
+ }
+
+ public entry newEntry(String key, String subject, String author, String ip, byte[] page) throws IOException {
+ return new entry(normalize(key), subject, author, ip, page);
+ }
+
+ public class entry {
+
+ String key;
+ Map record;
+
+ public entry(String nkey, String subject, String author, String ip, byte[] page) throws IOException {
+ record = new HashMap();
+ key = nkey;
+ if (key.length() > keyLength) key = key.substring(0, keyLength);
+ record.put("date", dateString());
+ if ((subject == null) || (subject.length() == 0)) subject = "";
+ record.put("subject", kelondroBase64Order.enhancedCoder.encode(subject.getBytes("UTF-8")));
+ if ((author == null) || (author.length() == 0)) author = "anonymous";
+ record.put("author", kelondroBase64Order.enhancedCoder.encode(author.getBytes("UTF-8")));
+ if ((ip == null) || (ip.length() == 0)) ip = "";
+ record.put("ip", ip);
+ if (page == null)
+ record.put("page", "");
+ else
+ record.put("page", kelondroBase64Order.enhancedCoder.encode(page));
+
+ wikiBoard.setAuthor(ip, author);
+ //System.out.println("DEBUG: setting author " + author + " for ip = " + ip + ", authors = " + authors.toString());
+ }
+
+ private entry(String key, Map record) {
+ this.key = key;
+ this.record = record;
+ }
+
+ public String key() {
+ return key;
+ }
+
+ public String subject() {
+ String a = (String) record.get("subject");
+ if (a == null) return "";
+ byte[] b = kelondroBase64Order.enhancedCoder.decode(a);
+ if (b == null) return "";
+ return new String(b);
+ }
+
+ public Date date() {
+ try {
+ String c = (String) record.get("date");
+ return SimpleFormatter.parse(c);
+ } catch (ParseException e) {
+ return new Date();
+ }
+ }
+
+ public String author() {
+ String a = (String) record.get("author");
+ if (a == null) return "anonymous";
+ byte[] b = kelondroBase64Order.enhancedCoder.decode(a);
+ if (b == null) return "anonymous";
+ return new String(b);
+ }
+
+ public byte[] page() {
+ String m = (String) record.get("page");
+ if (m == null) return new byte[0];
+ byte[] b = kelondroBase64Order.enhancedCoder.decode(m);
+ if (b == null) return "".getBytes();
+ return b;
+ }
+
+ }
+
+ public String write(entry page) {
+ // writes a new page and returns key
+ try {
+ datbase.set(page.key, page.record);
+ return page.key;
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ public entry read(String key) {
+ return read(key, datbase);
+ }
+
+ private entry read(String key, kelondroMap base) {
+ try {
+ key = normalize(key);
+ if (key.length() > keyLength) key = key.substring(0, keyLength);
+ Map record = base.get(key);
+ if (record == null) return newEntry(key, "", "anonymous", "127.0.0.1", "".getBytes());
+ return new entry(key, record);
+ } catch (IOException e) {
+ return null;
+ }
+ }
+
+ public Iterator keys(boolean up) throws IOException {
+ return datbase.keys(up, false);
+ }
+
+}
diff --git a/source/de/anomic/data/wikiBoard.java b/source/de/anomic/data/wikiBoard.java
index 188b63b8b..44943dcc2 100644
--- a/source/de/anomic/data/wikiBoard.java
+++ b/source/de/anomic/data/wikiBoard.java
@@ -67,7 +67,7 @@ public class wikiBoard {
private kelondroMap datbase = null;
private kelondroMap bkpbase = null;
- private HashMap authors = new HashMap();
+ private static HashMap authors = new HashMap();
public wikiBoard(File actpath, File bkppath, int bufferkb) {
new File(actpath.getParent()).mkdir();
@@ -143,11 +143,15 @@ public class wikiBoard {
return key;
}
- public String guessAuthor(String ip) {
+ public static String guessAuthor(String ip) {
String author = (String) authors.get(ip);
//yacyCore.log.logDebug("DEBUG: guessing author for ip = " + ip + " is '" + author + "', authors = " + authors.toString());
return author;
}
+
+ public static void setAuthor(String ip, String author) {
+ authors.put(ip,author);
+ }
public entry newEntry(String subject, String author, String ip, String reason, byte[] page) throws IOException {
return new entry(normalize(subject), author, ip, reason, page);
diff --git a/source/de/anomic/plasma/plasmaSwitchboard.java b/source/de/anomic/plasma/plasmaSwitchboard.java
index 4068b12dd..2b3847589 100644
--- a/source/de/anomic/plasma/plasmaSwitchboard.java
+++ b/source/de/anomic/plasma/plasmaSwitchboard.java
@@ -120,6 +120,7 @@ import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
+import de.anomic.data.blogBoard;
import de.anomic.data.bookmarksDB;
import de.anomic.data.messageBoard;
import de.anomic.data.wikiBoard;
@@ -186,6 +187,7 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
public plasmaCrawlStacker sbStackCrawlThread;
public messageBoard messageDB;
public wikiBoard wikiDB;
+ public blogBoard blogDB;
public static plasmaCrawlRobotsTxt robots;
public plasmaCrawlProfile profiles;
public plasmaCrawlProfile.entry defaultProxyProfile;
@@ -332,6 +334,7 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
int ramProfiles= (int) getConfigLong("ramCacheProfiles",1024) / 1024;
int ramPreNURL = (int) getConfigLong("ramCachePreNURL", 1024) / 1024;
int ramWiki = (int) getConfigLong("ramCacheWiki", 1024) / 1024;
+ int ramBlog = (int) getConfigLong("ramCacheBlog", 1024) / 1024;
this.log.logConfig("LURL Cache memory = " + ppRamString(ramLURL));
this.log.logConfig("NURL Cache memory = " + ppRamString(ramNURL));
this.log.logConfig("EURL Cache memory = " + ppRamString(ramEURL));
@@ -339,6 +342,7 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
this.log.logConfig("HTTP Cache memory = " + ppRamString(ramHTTP));
this.log.logConfig("Message Cache memory = " + ppRamString(ramMessage));
this.log.logConfig("Wiki Cache memory = " + ppRamString(ramWiki));
+ this.log.logConfig("Blog Cache memory = " + ppRamString(ramBlog));
this.log.logConfig("Robots Cache memory = " + ppRamString(ramRobots));
this.log.logConfig("Profiles Cache memory = " + ppRamString(ramProfiles));
this.log.logConfig("PreNURL Cache memory = " + ppRamString(ramPreNURL));
@@ -457,6 +461,9 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
// starting wiki
initWiki(ramWiki);
+ //starting blog
+ initBlog(ramBlog);
+
// Init User DB
this.log.logConfig("Loading User DB");
File userDbFile = new File(getRootPath(), "DATA/SETTINGS/user.db");
@@ -623,6 +630,14 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
", " + this.wikiDB.size() + " entries" +
", " + ppRamString(wikiDbFile.length()/1024));
}
+ public void initBlog(int ramBlog) {
+ this.log.logConfig("Starting Blog");
+ File blogDbFile = new File(workPath, "blog.db");
+ this.blogDB = new blogBoard(blogDbFile, ramBlog);
+ this.log.logConfig("Loaded Blog DB from file " + blogDbFile.getName() +
+ ", " + this.blogDB.size() + " entries" +
+ ", " + ppRamString(blogDbFile.length()/1024));
+ }
public void initBookmarks(){
this.log.logConfig("Loading Bookmarks DB");
File bookmarksFile = new File(workPath, "bookmarks.db");
@@ -816,6 +831,7 @@ public final class plasmaSwitchboard extends serverAbstractSwitch implements ser
this.dbImportManager.close();
cacheLoader.close();
wikiDB.close();
+ blogDB.close();
userDB.close();
bookmarksDB.close();
messageDB.close();
diff --git a/yacy.init b/yacy.init
index 28bc2e054..8cc74ccdb 100644
--- a/yacy.init
+++ b/yacy.init
@@ -487,6 +487,9 @@ ramCacheMessage = 8192
# ram cache for wiki.db
ramCacheWiki = 8192
+# ram cache for blog.db
+ramCacheBlog = 2048
+
# ram cache for news1.db
ramCacheNews = 8192