forked from I2P_Developers/i2p.i2p
2006-01-08 jrandom
* First pass of the new blog interface, though without much of the useful customization features (coming soon)
This commit is contained in:
@ -57,6 +57,7 @@ public class BlogInfo {
|
||||
public static final String DESCRIPTION = "Description";
|
||||
public static final String CONTACT_URL = "ContactURL";
|
||||
public static final String EDITION = "Edition";
|
||||
public static final String SUMMARY_ENTRY_ID = "SummaryEntryId";
|
||||
|
||||
public void load(InputStream in) throws IOException {
|
||||
Log log = I2PAppContext.getGlobalContext().logManager().getLog(getClass());
|
||||
|
127
apps/syndie/java/src/net/i2p/syndie/data/BlogInfoData.java
Normal file
127
apps/syndie/java/src/net/i2p/syndie/data/BlogInfoData.java
Normal file
@ -0,0 +1,127 @@
|
||||
package net.i2p.syndie.data;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import net.i2p.client.naming.PetName;
|
||||
import net.i2p.data.DataHelper;
|
||||
|
||||
/**
|
||||
* Contain the current supplementary data for rendering a blog, as opposed to
|
||||
* just verifying and rendering a post.
|
||||
*/
|
||||
public class BlogInfoData {
|
||||
private BlogURI _dataEntryId;
|
||||
/** list of List of PetName instances that the blog refers to */
|
||||
private List _referenceGroups;
|
||||
/** customized style config */
|
||||
private Properties _styleOverrides;
|
||||
/** the blog's logo */
|
||||
private Attachment _logo;
|
||||
private List _otherAttachments;
|
||||
|
||||
public static final String ATTACHMENT_LOGO = "logo.png";
|
||||
public static final String ATTACHMENT_REFERENCE_GROUPS = "groups.txt";
|
||||
public static final String ATTACHMENT_STYLE_OVERRIDE = "style.cfg";
|
||||
/** identifies a post as being a blog info data, not a content bearing post */
|
||||
public static final String TAG = "BlogInfoData";
|
||||
|
||||
public BlogInfoData() {}
|
||||
|
||||
public BlogURI getEntryId() { return _dataEntryId; }
|
||||
public boolean isLogoSpecified() { return _logo != null; }
|
||||
public Attachment getLogo() { return _logo; }
|
||||
public boolean isStyleSpecified() { return _styleOverrides != null; }
|
||||
public Properties getStyleOverrides() { return _styleOverrides; }
|
||||
public int getReferenceGroupCount() { return _referenceGroups != null ? _referenceGroups.size() : 0; }
|
||||
/** list of PetName elements to be included in the list */
|
||||
public List getReferenceGroup(int groupNum) { return (List)_referenceGroups.get(groupNum); }
|
||||
public int getOtherAttachmentCount() { return _otherAttachments != null ? _otherAttachments.size() : 0; }
|
||||
public Attachment getOtherAttachment(int num) { return (Attachment)_otherAttachments.get(num); }
|
||||
public Attachment getOtherAttachment(String name) {
|
||||
for (int i = 0; i < _otherAttachments.size(); i++) {
|
||||
Attachment a = (Attachment)_otherAttachments.get(i);
|
||||
if (a.getName().equals(name))
|
||||
return a;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void writeLogo(OutputStream out) throws IOException {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = _logo.getDataStream();
|
||||
byte buf[] = new byte[4096];
|
||||
int read = 0;
|
||||
while ( (read = in.read(buf)) != -1)
|
||||
out.write(buf, 0, read);
|
||||
} finally {
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void load(EntryContainer entry) throws IOException {
|
||||
_dataEntryId = entry.getURI();
|
||||
Attachment attachments[] = entry.getAttachments();
|
||||
for (int i = 0; i < attachments.length; i++) {
|
||||
if (ATTACHMENT_LOGO.equals(attachments[i].getName())) {
|
||||
_logo = attachments[i];
|
||||
} else if (ATTACHMENT_REFERENCE_GROUPS.equals(attachments[i].getName())) {
|
||||
readReferenceGroups(attachments[i]);
|
||||
} else if (ATTACHMENT_STYLE_OVERRIDE.equals(attachments[i].getName())) {
|
||||
readStyleOverride(attachments[i]);
|
||||
} else {
|
||||
if (_otherAttachments == null)
|
||||
_otherAttachments = new ArrayList();
|
||||
_otherAttachments.add(attachments[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void readReferenceGroups(Attachment att) throws IOException {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = att.getDataStream();
|
||||
StringBuffer line = new StringBuffer(128);
|
||||
List groups = new ArrayList();
|
||||
String prevGroup = null;
|
||||
List defaultGroup = new ArrayList();
|
||||
while (true) {
|
||||
boolean ok = DataHelper.readLine(in, line);
|
||||
if (line.length() > 0) {
|
||||
PetName pn = new PetName(line.toString().trim());
|
||||
if (pn.getGroupCount() <= 0) {
|
||||
defaultGroup.add(pn);
|
||||
} else if (pn.getGroup(0).equals(prevGroup)) {
|
||||
List curGroup = (List)groups.get(groups.size()-1);
|
||||
curGroup.add(pn);
|
||||
} else {
|
||||
List curGroup = new ArrayList();
|
||||
curGroup.add(pn);
|
||||
groups.add(curGroup);
|
||||
prevGroup = pn.getGroup(0);
|
||||
}
|
||||
}
|
||||
if (!ok)
|
||||
break;
|
||||
}
|
||||
if (defaultGroup.size() > 0)
|
||||
groups.add(defaultGroup);
|
||||
_referenceGroups = groups;
|
||||
} finally {
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
|
||||
private void readStyleOverride(Attachment att) throws IOException {
|
||||
InputStream in = null;
|
||||
try {
|
||||
in = att.getDataStream();
|
||||
Properties props = new Properties();
|
||||
DataHelper.loadProps(props, in);
|
||||
_styleOverrides = props;
|
||||
} finally {
|
||||
if (in != null) try { in.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
}
|
@ -59,7 +59,10 @@ public class EntryContainer {
|
||||
public EntryContainer(BlogURI uri, String tags[], byte smlData[]) {
|
||||
this();
|
||||
_entryURI = uri;
|
||||
_entryData = new Entry(DataHelper.getUTF8(smlData));
|
||||
if ( (smlData == null) || (smlData.length <= 0) )
|
||||
_entryData = new Entry(null);
|
||||
else
|
||||
_entryData = new Entry(DataHelper.getUTF8(smlData));
|
||||
setHeader(HEADER_BLOGKEY, Base64.encode(uri.getKeyHash().getData()));
|
||||
StringBuffer buf = new StringBuffer();
|
||||
for (int i = 0; tags != null && i < tags.length; i++)
|
||||
@ -203,10 +206,13 @@ public class EntryContainer {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
ZipOutputStream out = new ZipOutputStream(baos);
|
||||
ZipEntry ze = new ZipEntry(ZIP_ENTRY);
|
||||
byte data[] = DataHelper.getUTF8(_entryData.getText());
|
||||
byte data[] = null;
|
||||
if (_entryData.getText() != null)
|
||||
data = DataHelper.getUTF8(_entryData.getText());
|
||||
ze.setTime(0);
|
||||
out.putNextEntry(ze);
|
||||
out.write(data);
|
||||
if (data != null)
|
||||
out.write(data);
|
||||
out.closeEntry();
|
||||
for (int i = 0; (_attachments != null) && (i < _attachments.length); i++) {
|
||||
ze = new ZipEntry(ZIP_ATTACHMENT_PREFIX + i + ZIP_ATTACHMENT_SUFFIX);
|
||||
@ -270,6 +276,9 @@ public class EntryContainer {
|
||||
//System.out.println("Read entry [" + name + "] with size=" + entryData.length);
|
||||
}
|
||||
|
||||
if (_entryData == null)
|
||||
_entryData = new Entry(null);
|
||||
|
||||
_attachments = new Attachment[attachments.size()];
|
||||
|
||||
for (int i = 0; i < attachments.size(); i++) {
|
||||
|
189
apps/syndie/java/src/net/i2p/syndie/sml/BlogRenderer.java
Normal file
189
apps/syndie/java/src/net/i2p/syndie/sml/BlogRenderer.java
Normal file
@ -0,0 +1,189 @@
|
||||
package net.i2p.syndie.sml;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.naming.PetName;
|
||||
import net.i2p.data.*;
|
||||
import net.i2p.syndie.data.*;
|
||||
import net.i2p.syndie.web.*;
|
||||
|
||||
/**
|
||||
* Renders posts for display within the blog view
|
||||
*
|
||||
*/
|
||||
public class BlogRenderer extends HTMLRenderer {
|
||||
private BlogInfo _blog;
|
||||
private BlogInfoData _data;
|
||||
public BlogRenderer(I2PAppContext ctx, BlogInfo info, BlogInfoData data) {
|
||||
super(ctx);
|
||||
_blog = info;
|
||||
_data = data;
|
||||
}
|
||||
|
||||
public void receiveHeaderEnd() {
|
||||
_preBodyBuffer.append("<div class=\"syndieBlogPost\"><hr style=\"display: none\" />\n");
|
||||
_preBodyBuffer.append("<div class=\"syndieBlogPostHeader\">\n");
|
||||
_preBodyBuffer.append("<div class=\"syndieBlogPostSubject\">");
|
||||
String subject = (String)_headers.get(HEADER_SUBJECT);
|
||||
if (subject == null)
|
||||
subject = "[no subject]";
|
||||
String tags[] = _entry.getTags();
|
||||
for (int i = 0; (tags != null) && (i < tags.length); i++)
|
||||
displayTag(_preBodyBuffer, _data, tags[i]);
|
||||
_preBodyBuffer.append(getSpan("subjectText")).append(sanitizeString(subject)).append("</span></div>\n");
|
||||
|
||||
String name = getAuthor();
|
||||
String when = getEntryDate(_entry.getURI().getEntryId());
|
||||
_preBodyBuffer.append("<div class=\"syndieBlogPostFrom\">Posted by: <a href=\"");
|
||||
_preBodyBuffer.append(getMetadataURL(_entry.getURI().getKeyHash()));
|
||||
_preBodyBuffer.append("\" title=\"View their profile\">");
|
||||
_preBodyBuffer.append(sanitizeString(name));
|
||||
_preBodyBuffer.append("</a> on ");
|
||||
_preBodyBuffer.append(when);
|
||||
_preBodyBuffer.append("</div>\n");
|
||||
_preBodyBuffer.append("</div><!-- end syndieBlogPostHeader -->\n");
|
||||
|
||||
_preBodyBuffer.append("<div class=\"syndieBlogPostSummary\">\n");
|
||||
}
|
||||
|
||||
public void receiveEnd() {
|
||||
_postBodyBuffer.append("</div><!-- end syndieBlogPostSummary -->\n");
|
||||
_postBodyBuffer.append("<div class=\"syndieBlogPostDetails\">\n");
|
||||
int childCount = getChildCount(_archive.getIndex().getThreadedIndex().getNode(_entry.getURI()));
|
||||
if ( (_cutReached || childCount > 0) && (_cutBody) ) {
|
||||
_postBodyBuffer.append("<a href=\"");
|
||||
_postBodyBuffer.append(getEntryURL()).append("\" title=\"View comments on this post\">Read more</a> ");
|
||||
}
|
||||
if (childCount > 0) {
|
||||
_postBodyBuffer.append(childCount).append(" ");
|
||||
if (childCount > 1)
|
||||
_postBodyBuffer.append(" comments already, ");
|
||||
else
|
||||
_postBodyBuffer.append(" comment already, ");
|
||||
}
|
||||
_postBodyBuffer.append("<a href=\"");
|
||||
_postBodyBuffer.append(getReplyURL()).append("\" title=\"Reply to this post\">Leave a comment</a>\n");
|
||||
_postBodyBuffer.append("</div><!-- end syndieBlogPostDetails -->\n");
|
||||
_postBodyBuffer.append("</div><!-- end syndieBlogPost -->\n\n");
|
||||
}
|
||||
private int getChildCount(ThreadNode node) {
|
||||
int nodes = 0;
|
||||
for (int i = 0; i < node.getChildCount(); i++) {
|
||||
nodes++;
|
||||
nodes += getChildCount(node.getChild(i));
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private String getAuthor() {
|
||||
PetName pn = null;
|
||||
if ( (_entry != null) && (_user != null) )
|
||||
pn = _user.getPetNameDB().getByLocation(_entry.getURI().getKeyHash().toBase64());
|
||||
if (pn != null)
|
||||
return pn.getName();
|
||||
BlogInfo info = null;
|
||||
if (_entry != null) {
|
||||
info = _archive.getBlogInfo(_entry.getURI());
|
||||
if (info != null) {
|
||||
String str = info.getProperty(BlogInfo.NAME);
|
||||
if (str != null)
|
||||
return str;
|
||||
}
|
||||
return _entry.getURI().getKeyHash().toBase64().substring(0,6);
|
||||
} else {
|
||||
return "No name?";
|
||||
}
|
||||
}
|
||||
|
||||
private void displayTag(StringBuffer buf, BlogInfoData data, String tag) {
|
||||
//buf.append("<a href=\"");
|
||||
//buf.append(getPageURL(_blog.getKey().calculateHash(), tag, -1, null, 5, 0, false, true));
|
||||
//buf.append("\" title=\"Filter the blog by the tag '").append(sanitizeTagParam(tag)).append("'\">");
|
||||
if ( (tag == null) || ("[none]".equals(tag) ) )
|
||||
return;
|
||||
buf.append("<img src=\"").append(getTagIconURL(tag)).append("\" alt=\"");
|
||||
buf.append(sanitizeTagParam(tag)).append("\" />");
|
||||
//buf.append("</a>");
|
||||
buf.append(" ");
|
||||
}
|
||||
|
||||
public String getMetadataURL(Hash blog) { return ThreadedHTMLRenderer.buildProfileURL(blog); }
|
||||
private String getTagIconURL(String tag) {
|
||||
return "viewicon.jsp?tag=" + Base64.encode(tag) + "&" +
|
||||
ViewBlogServlet.PARAM_BLOG + "=" + _blog.getKey().calculateHash().toBase64();
|
||||
}
|
||||
|
||||
private String getReplyURL() {
|
||||
String subject = (String)_headers.get(HEADER_SUBJECT);
|
||||
if (subject != null) {
|
||||
if (!subject.startsWith("re:"))
|
||||
subject = "re: " + subject;
|
||||
} else {
|
||||
subject = "re: ";
|
||||
}
|
||||
return "post.jsp?" + PostServlet.PARAM_PARENT + "="
|
||||
+ Base64.encode(_entry.getURI().getKeyHash().toBase64() + "/" + _entry.getURI().getEntryId()) + "&"
|
||||
+ PostServlet.PARAM_SUBJECT + "=" + sanitizeTagParam(subject) + "&";
|
||||
}
|
||||
|
||||
protected String getEntryURL() { return getEntryURL(_user != null ? _user.getShowImages() : true); }
|
||||
protected String getEntryURL(boolean showImages) {
|
||||
if (_entry == null) return "unknown";
|
||||
return "blog.jsp?"
|
||||
+ ViewBlogServlet.PARAM_BLOG + "=" + _blog.getKey().calculateHash().toBase64() + "&"
|
||||
+ ViewBlogServlet.PARAM_ENTRY + "="
|
||||
+ Base64.encode(_entry.getURI().getKeyHash().getData()) + '/' + _entry.getURI().getEntryId();
|
||||
}
|
||||
|
||||
protected String getAttachmentURLBase() {
|
||||
return "invalid";
|
||||
}
|
||||
|
||||
protected String getAttachmentURL(int id) {
|
||||
if (_entry == null) return "unknown";
|
||||
return "blog.jsp?"
|
||||
+ ViewBlogServlet.PARAM_BLOG + "=" + _blog.getKey().calculateHash().toBase64() + "&"
|
||||
+ ViewBlogServlet.PARAM_ATTACHMENT + "="
|
||||
+ Base64.encode(_entry.getURI().getKeyHash().getData()) + "/"
|
||||
+ _entry.getURI().getEntryId() + "/"
|
||||
+ id;
|
||||
}
|
||||
|
||||
public String getPageURL(String entry) {
|
||||
StringBuffer buf = new StringBuffer(128);
|
||||
buf.append("blog.jsp?");
|
||||
buf.append(ViewBlogServlet.PARAM_BLOG).append(_blog.getKey().calculateHash().toBase64()).append("&");
|
||||
|
||||
if (entry != null) {
|
||||
if (entry.startsWith("entry://"))
|
||||
entry = entry.substring("entry://".length());
|
||||
else if (entry.startsWith("blog://"))
|
||||
entry = entry.substring("blog://".length());
|
||||
int split = entry.indexOf('/');
|
||||
if (split > 0) {
|
||||
buf.append(ViewBlogServlet.PARAM_ENTRY).append("=");
|
||||
buf.append(sanitizeTagParam(entry.substring(0, split))).append('/');
|
||||
buf.append(sanitizeTagParam(entry.substring(split+1))).append("&");
|
||||
}
|
||||
}
|
||||
return buf.toString();
|
||||
}
|
||||
public String getPageURL(Hash blog, String tag, long entryId, String group, int numPerPage, int pageNum, boolean expandEntries, boolean showImages) {
|
||||
StringBuffer buf = new StringBuffer(128);
|
||||
buf.append("blog.jsp?");
|
||||
buf.append(ViewBlogServlet.PARAM_BLOG).append("=");
|
||||
buf.append(_blog.getKey().calculateHash().toBase64()).append("&");
|
||||
|
||||
if ( (blog != null) && (entryId > 0) ) {
|
||||
buf.append(ViewBlogServlet.PARAM_ENTRY).append("=");
|
||||
buf.append(blog.toBase64()).append('/');
|
||||
buf.append(entryId).append("&");
|
||||
}
|
||||
if (tag != null)
|
||||
buf.append(ViewBlogServlet.PARAM_TAG).append('=').append(sanitizeTagParam(tag)).append("&");
|
||||
if ( (pageNum >= 0) && (numPerPage > 0) )
|
||||
buf.append(ViewBlogServlet.PARAM_OFFSET).append('=').append(pageNum*numPerPage).append("&");
|
||||
return buf.toString();
|
||||
}
|
||||
}
|
@ -8,7 +8,7 @@ import net.i2p.util.Log;
|
||||
*
|
||||
*/
|
||||
public class EventReceiverImpl implements SMLParser.EventReceiver {
|
||||
private I2PAppContext _context;
|
||||
protected I2PAppContext _context;
|
||||
private Log _log;
|
||||
|
||||
public EventReceiverImpl(I2PAppContext ctx) {
|
||||
|
@ -1017,10 +1017,10 @@ public class HTMLRenderer extends EventReceiverImpl {
|
||||
_entry.getURI().getEntryId();
|
||||
}
|
||||
|
||||
protected String getAttachmentURLBase() { return "viewattachment.jsp"; }
|
||||
protected String getAttachmentURLBase() { return "viewattachment.jsp?"; }
|
||||
protected String getAttachmentURL(int id) {
|
||||
if (_entry == null) return "unknown";
|
||||
return getAttachmentURLBase() + "?" +
|
||||
return getAttachmentURLBase() +
|
||||
ArchiveViewerBean.PARAM_BLOG + "=" +
|
||||
Base64.encode(_entry.getURI().getKeyHash().getData()) +
|
||||
"&" + ArchiveViewerBean.PARAM_ENTRY + "=" + _entry.getURI().getEntryId() +
|
||||
|
@ -596,9 +596,11 @@ public class ArchiveViewerBean {
|
||||
}
|
||||
|
||||
public static void renderAttachment(Map parameters, OutputStream out) throws IOException {
|
||||
Attachment a = getAttachment(parameters);
|
||||
renderAttachment(getAttachment(parameters), out);
|
||||
}
|
||||
public static void renderAttachment(Attachment a, OutputStream out) throws IOException {
|
||||
if (a == null) {
|
||||
renderInvalidAttachment(parameters, out);
|
||||
renderInvalidAttachment(out);
|
||||
} else {
|
||||
InputStream data = a.getDataStream();
|
||||
byte buf[] = new byte[1024];
|
||||
@ -610,17 +612,21 @@ public class ArchiveViewerBean {
|
||||
}
|
||||
|
||||
public static final String getAttachmentContentType(Map parameters) {
|
||||
Attachment a = getAttachment(parameters);
|
||||
if (a == null)
|
||||
return getAttachmentContentType(getAttachment(parameters));
|
||||
}
|
||||
public static final String getAttachmentContentType(Attachment attachment) {
|
||||
if (attachment == null)
|
||||
return "text/html";
|
||||
String mime = a.getMimeType();
|
||||
String mime = attachment.getMimeType();
|
||||
if ( (mime != null) && ((mime.startsWith("image/") || mime.startsWith("text/plain"))) )
|
||||
return mime;
|
||||
return "application/octet-stream";
|
||||
}
|
||||
|
||||
public static final boolean getAttachmentShouldShowInline(Map parameters) {
|
||||
Attachment a = getAttachment(parameters);
|
||||
return getAttachmentShouldShowInline(getAttachment(parameters));
|
||||
}
|
||||
public static final boolean getAttachmentShouldShowInline(Attachment a) {
|
||||
if (a == null)
|
||||
return true;
|
||||
String mime = a.getMimeType();
|
||||
@ -631,7 +637,9 @@ public class ArchiveViewerBean {
|
||||
}
|
||||
|
||||
public static final int getAttachmentContentLength(Map parameters) {
|
||||
Attachment a = getAttachment(parameters);
|
||||
return getAttachmentContentLength(getAttachment(parameters));
|
||||
}
|
||||
public static final int getAttachmentContentLength(Attachment a) {
|
||||
if (a != null)
|
||||
return a.getDataLength();
|
||||
else
|
||||
@ -639,7 +647,9 @@ public class ArchiveViewerBean {
|
||||
}
|
||||
|
||||
public static final String getAttachmentFilename(Map parameters) {
|
||||
Attachment a = getAttachment(parameters);
|
||||
return getAttachmentFilename(getAttachment(parameters));
|
||||
}
|
||||
public static final String getAttachmentFilename(Attachment a) {
|
||||
if (a != null)
|
||||
return a.getName();
|
||||
else
|
||||
@ -667,7 +677,7 @@ public class ArchiveViewerBean {
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void renderInvalidAttachment(Map parameters, OutputStream out) throws IOException {
|
||||
private static void renderInvalidAttachment(OutputStream out) throws IOException {
|
||||
out.write(DataHelper.getUTF8("<span class=\"b_msgErr\">No such entry, or no such attachment</span>"));
|
||||
}
|
||||
|
||||
|
270
apps/syndie/java/src/net/i2p/syndie/web/BlogConfigBean.java
Normal file
270
apps/syndie/java/src/net/i2p/syndie/web/BlogConfigBean.java
Normal file
@ -0,0 +1,270 @@
|
||||
package net.i2p.syndie.web;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.naming.PetName;
|
||||
import net.i2p.data.DataHelper;
|
||||
import net.i2p.syndie.*;
|
||||
import net.i2p.syndie.data.*;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class BlogConfigBean {
|
||||
private I2PAppContext _context;
|
||||
private Log _log;
|
||||
private User _user;
|
||||
private String _title;
|
||||
private String _description;
|
||||
private String _contactInfo;
|
||||
/** list of list of PetNames */
|
||||
private List _groups;
|
||||
private Properties _styleOverrides;
|
||||
private File _logo;
|
||||
private boolean _loaded;
|
||||
private boolean _updated;
|
||||
|
||||
public BlogConfigBean() {
|
||||
_context = I2PAppContext.getGlobalContext();
|
||||
_log = _context.logManager().getLog(BlogConfigBean.class);
|
||||
_groups = new ArrayList();
|
||||
_styleOverrides = new Properties();
|
||||
}
|
||||
|
||||
public User getUser() { return _user; }
|
||||
public void setUser(User user) {
|
||||
_user = user;
|
||||
_title = null;
|
||||
_description = null;
|
||||
_contactInfo = null;
|
||||
_groups.clear();
|
||||
_styleOverrides.clear();
|
||||
if (_logo != null)
|
||||
_logo.delete();
|
||||
_logo = null;
|
||||
_loaded = false;
|
||||
_updated = false;
|
||||
load();
|
||||
}
|
||||
public String getTitle() { return _title; }
|
||||
public void setTitle(String title) {
|
||||
_title = title;
|
||||
_updated = true;
|
||||
}
|
||||
public String getDescription() { return _description; }
|
||||
public void setDescription(String desc) {
|
||||
_description = desc;
|
||||
_updated = true;
|
||||
}
|
||||
public String getContactInfo() { return _contactInfo; }
|
||||
public void setContactInfo(String info) {
|
||||
_contactInfo = info;
|
||||
_updated = true;
|
||||
}
|
||||
public int getGroupCount() { return _groups.size(); }
|
||||
/** gets the actual modifiable list of PetName instances */
|
||||
public List getGroup(int i) { return (List)_groups.get(i); }
|
||||
/** gets the actual modifiable list of PetName instances */
|
||||
public List getGroup(String name) {
|
||||
for (int i = 0; i < _groups.size(); i++) {
|
||||
List grp = (List)_groups.get(i);
|
||||
if (grp.size() > 0) {
|
||||
PetName pn = (PetName)grp.get(0);
|
||||
if ( (pn.getGroupCount() == 0) && ( (name == null) || (name.length() <= 0) ) )
|
||||
return grp;
|
||||
String curGroup = pn.getGroup(0);
|
||||
if (curGroup.equals(name))
|
||||
return grp;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/** adds the given element to the appropriate group (creating a new one if necessary) */
|
||||
public void add(PetName pn) {
|
||||
String groupName = null;
|
||||
if (pn.getGroupCount() > 0)
|
||||
groupName = pn.getGroup(0);
|
||||
List group = getGroup(groupName);
|
||||
if (group == null) {
|
||||
group = new ArrayList(4);
|
||||
group.add(pn);
|
||||
_groups.add(group);
|
||||
} else {
|
||||
group.add(pn);
|
||||
}
|
||||
}
|
||||
public void remove(PetName pn) {
|
||||
String groupName = null;
|
||||
if (pn.getGroupCount() > 0)
|
||||
groupName = pn.getGroup(0);
|
||||
List group = getGroup(groupName);
|
||||
if (group != null) {
|
||||
group.remove(pn);
|
||||
if (group.size() <= 0)
|
||||
_groups.remove(group);
|
||||
}
|
||||
}
|
||||
public void remove(String name) {
|
||||
for (int i = 0; i < getGroupCount(); i++) {
|
||||
List group = getGroup(i);
|
||||
for (int j = 0; j < group.size(); j++) {
|
||||
PetName pn = (PetName)group.get(j);
|
||||
if (pn.getName().equals(name)) {
|
||||
group.remove(j);
|
||||
if (group.size() <= 0)
|
||||
_groups.remove(group);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/** take note that the groups have been updated in some way (reordered, etc) */
|
||||
public void groupsUpdated() { _updated = true; }
|
||||
public String getStyleOverride(String prop) { return _styleOverrides.getProperty(prop); }
|
||||
public void setStyleOverride(String prop, String val) {
|
||||
_styleOverrides.setProperty(prop, val);
|
||||
_updated = true;
|
||||
}
|
||||
public void unsetStyleOverride(String prop) {
|
||||
_styleOverrides.remove(prop);
|
||||
_updated = true;
|
||||
}
|
||||
public File getLogo() { return _logo; }
|
||||
public void setLogo(File logo) {
|
||||
if ( (logo != null) && (logo.length() > 128*1024) ) {
|
||||
_log.error("Refusing a logo more than 128KB");
|
||||
return;
|
||||
}
|
||||
_logo = logo;
|
||||
_updated = true;
|
||||
}
|
||||
public boolean hasPendingChanges() { return _updated; }
|
||||
|
||||
private void load() {
|
||||
Archive archive = BlogManager.instance().getArchive();
|
||||
BlogInfo info = archive.getBlogInfo(_user.getBlog());
|
||||
if (info != null) {
|
||||
_title = info.getProperty(BlogInfo.NAME);
|
||||
_description = info.getProperty(BlogInfo.DESCRIPTION);
|
||||
_contactInfo = info.getProperty(BlogInfo.CONTACT_URL);
|
||||
String id = info.getProperty(BlogInfo.SUMMARY_ENTRY_ID);
|
||||
if (id != null) {
|
||||
BlogURI uri = new BlogURI(id);
|
||||
EntryContainer entry = archive.getEntry(uri);
|
||||
if (entry != null) {
|
||||
BlogInfoData data = new BlogInfoData();
|
||||
try {
|
||||
data.load(entry);
|
||||
if (data.isLogoSpecified()) {
|
||||
File logo = File.createTempFile("logo", ".png", BlogManager.instance().getTempDir());
|
||||
FileOutputStream os = null;
|
||||
try {
|
||||
os = new FileOutputStream(logo);
|
||||
data.writeLogo(os);
|
||||
_logo = logo;
|
||||
} finally {
|
||||
if (os != null) try { os.close(); } catch (IOException ioe) {}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < data.getReferenceGroupCount(); i++) {
|
||||
List group = (List)data.getReferenceGroup(i);
|
||||
for (int j = 0; j < group.size(); j++) {
|
||||
PetName pn = (PetName)group.get(j);
|
||||
add(pn);
|
||||
}
|
||||
}
|
||||
_styleOverrides.putAll(data.getStyleOverrides());
|
||||
} catch (IOException ioe) {
|
||||
_log.warn("Unable to load the blog info data from " + uri, ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
_loaded = true;
|
||||
}
|
||||
|
||||
public boolean publishChanges() throws IOException {
|
||||
FileInputStream logo = null;
|
||||
try {
|
||||
if (_logo != null)
|
||||
logo = new FileInputStream(_logo);
|
||||
InputStream styleStream = createStyleStream();
|
||||
InputStream groupStream = createGroupStream();
|
||||
|
||||
String tags = BlogInfoData.TAG;
|
||||
String subject = "n/a";
|
||||
String headers = "";
|
||||
String sml = "";
|
||||
List filenames = new ArrayList();
|
||||
List filestreams = new ArrayList();
|
||||
List filetypes = new ArrayList();
|
||||
if (logo != null) {
|
||||
filenames.add(BlogInfoData.ATTACHMENT_LOGO);
|
||||
filestreams.add(logo);
|
||||
filetypes.add("image/png");
|
||||
}
|
||||
filenames.add(BlogInfoData.ATTACHMENT_STYLE_OVERRIDE);
|
||||
filestreams.add(styleStream);
|
||||
filetypes.add("text/plain");
|
||||
filenames.add(BlogInfoData.ATTACHMENT_REFERENCE_GROUPS);
|
||||
filestreams.add(groupStream);
|
||||
filetypes.add("text/plain");
|
||||
|
||||
BlogURI uri = BlogManager.instance().createBlogEntry(_user, subject, tags, headers, sml,
|
||||
filenames, filestreams, filetypes);
|
||||
if (uri != null) {
|
||||
Archive archive = BlogManager.instance().getArchive();
|
||||
BlogInfo info = archive.getBlogInfo(_user.getBlog());
|
||||
if (info != null) {
|
||||
String props[] = info.getProperties();
|
||||
Properties opts = new Properties();
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (!props[i].equals(BlogInfo.SUMMARY_ENTRY_ID))
|
||||
opts.setProperty(props[i], info.getProperty(props[i]));
|
||||
}
|
||||
opts.setProperty(BlogInfo.SUMMARY_ENTRY_ID, uri.toString());
|
||||
boolean updated = BlogManager.instance().updateMetadata(_user, _user.getBlog(), opts);
|
||||
if (updated) {
|
||||
// ok great, published locally, though should we push it to others?
|
||||
_log.info("Blog summary updated for " + _user + " in " + uri.toString());
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
_log.error("Info is not known for " + _user.getBlog().toBase64());
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
_log.error("Error creating the summary entry");
|
||||
return false;
|
||||
}
|
||||
} finally {
|
||||
if (logo != null) try { logo.close(); } catch (IOException ioe) {}
|
||||
// the other streams are in-memory, drop with the scope
|
||||
}
|
||||
return false;
|
||||
}
|
||||
private InputStream createStyleStream() throws IOException {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
if (_styleOverrides != null) {
|
||||
for (Iterator iter = _styleOverrides.keySet().iterator(); iter.hasNext(); ) {
|
||||
String key = (String)iter.next();
|
||||
String val = _styleOverrides.getProperty(key);
|
||||
buf.append(key).append('=').append(val).append('\n');
|
||||
}
|
||||
}
|
||||
return new ByteArrayInputStream(DataHelper.getUTF8(buf));
|
||||
}
|
||||
private InputStream createGroupStream() throws IOException {
|
||||
StringBuffer buf = new StringBuffer(1024);
|
||||
for (int i = 0; i < _groups.size(); i++) {
|
||||
List group = (List)_groups.get(i);
|
||||
for (int j = 0; j < group.size(); j++) {
|
||||
PetName pn = (PetName)group.get(j);
|
||||
buf.append(pn.toString()).append('\n');
|
||||
}
|
||||
}
|
||||
return new ByteArrayInputStream(DataHelper.getUTF8(buf));
|
||||
}
|
||||
}
|
231
apps/syndie/java/src/net/i2p/syndie/web/BlogConfigServlet.java
Normal file
231
apps/syndie/java/src/net/i2p/syndie/web/BlogConfigServlet.java
Normal file
@ -0,0 +1,231 @@
|
||||
package net.i2p.syndie.web;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.ServletException;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.naming.*;
|
||||
import net.i2p.data.*;
|
||||
import net.i2p.syndie.*;
|
||||
import net.i2p.syndie.data.*;
|
||||
import net.i2p.syndie.sml.*;
|
||||
|
||||
/**
|
||||
* Display our blog config, and let us edit it through several screens
|
||||
*
|
||||
*/
|
||||
public class BlogConfigServlet extends BaseServlet {
|
||||
private static final String ATTR_CONFIG_BEAN = "__blogConfigBean";
|
||||
public static final String PARAM_CONFIG_SCREEN = "screen";
|
||||
public static final String SCREEN_GENERAL = "general";
|
||||
public static final String SCREEN_REFERENCES = "references";
|
||||
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
|
||||
int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException {
|
||||
if ( (user == null) || (!user.getAuthenticated() && !BlogManager.instance().isSingleUser())) {
|
||||
out.write("You must be logged in to edit your profile");
|
||||
return;
|
||||
}
|
||||
BlogConfigBean bean = (BlogConfigBean)req.getSession().getAttribute(ATTR_CONFIG_BEAN);
|
||||
if (bean == null) {
|
||||
bean = new BlogConfigBean();
|
||||
bean.setUser(user);
|
||||
}
|
||||
|
||||
// handle actions here...
|
||||
// on done handling
|
||||
|
||||
String screen = req.getParameter(PARAM_CONFIG_SCREEN);
|
||||
if (screen == null)
|
||||
screen = SCREEN_GENERAL;
|
||||
out.write("todo: Display screen " + screen);
|
||||
/*
|
||||
if (SCREEN_REFERENCES.equals(screen)) {
|
||||
displayReferencesScreen(req, out, bean);
|
||||
} else {
|
||||
displayGeneralScreen(req, out, bean);
|
||||
}
|
||||
*/
|
||||
}
|
||||
/*
|
||||
private void renderMyProfile(User user, String baseURI, PrintWriter out, Archive archive) throws IOException {
|
||||
BlogInfo info = archive.getBlogInfo(user.getBlog());
|
||||
if (info == null)
|
||||
return;
|
||||
|
||||
out.write("<!-- " + info.toString() + "-->\n");
|
||||
out.write("<form action=\"" + baseURI + "\" method=\"POST\">\n");
|
||||
writeAuthActionFields(out);
|
||||
// now add the form to update
|
||||
out.write("<tr><td colspan=\"3\">Your profile</td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">Name: <input type=\"text\" name=\""
|
||||
+ ThreadedHTMLRenderer.PARAM_PROFILE_NAME + "\" value=\""
|
||||
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.NAME)) + "\"></td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">Account description: <input type=\"text\" name=\""
|
||||
+ ThreadedHTMLRenderer.PARAM_PROFILE_DESC + "\" value=\""
|
||||
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.DESCRIPTION)) + "\"></td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">Contact information: <input type=\"text\" name=\""
|
||||
+ ThreadedHTMLRenderer.PARAM_PROFILE_URL + "\" value=\""
|
||||
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.CONTACT_URL)) + "\"></td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">Other attributes:<br /><textarea rows=\"3\" name=\""
|
||||
+ ThreadedHTMLRenderer.PARAM_PROFILE_OTHER + "\" cols=\"60\">");
|
||||
String props[] = info.getProperties();
|
||||
if (props != null) {
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (!BlogInfo.NAME.equals(props[i]) &&
|
||||
!BlogInfo.DESCRIPTION.equals(props[i]) &&
|
||||
!BlogInfo.EDITION.equals(props[i]) &&
|
||||
!BlogInfo.OWNER_KEY.equals(props[i]) &&
|
||||
!BlogInfo.POSTERS.equals(props[i]) &&
|
||||
!BlogInfo.SIGNATURE.equals(props[i]) &&
|
||||
!BlogInfo.CONTACT_URL.equals(props[i])) {
|
||||
out.write(HTMLRenderer.sanitizeString(props[i], false) + ": "
|
||||
+ HTMLRenderer.sanitizeString(info.getProperty(props[i]), false) + "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
out.write("</textarea></td></tr>\n");
|
||||
|
||||
if (user.getAuthenticated()) {
|
||||
if ( (user.getUsername() == null) || (user.getUsername().equals(BlogManager.instance().getDefaultLogin())) ) {
|
||||
// this is the default user, don't let them change the password
|
||||
} else {
|
||||
out.write("<tr><td colspan=\"3\">Old Password: <input type=\"password\" name=\"oldPassword\" /></td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">Password: <input type=\"password\" name=\"password\" /></td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">Password again: <input type=\"password\" name=\"passwordConfirm\" /></td></tr>\n");
|
||||
}
|
||||
if (!BlogManager.instance().authorizeRemote(user)) {
|
||||
out.write("<tr><td colspan=\"3\">To access the remote functionality, please specify the administrative password: <br />\n" +
|
||||
"<input type=\"password\" name=\"adminPass\" /></td></tr>\n");
|
||||
}
|
||||
}
|
||||
|
||||
out.write("<tr><td colspan=\"3\"><input type=\"submit\" name=\"action\" value=\"Update profile\" /></td></tr>\n");
|
||||
out.write("</form>\n");
|
||||
}
|
||||
|
||||
private void renderProfile(User user, String baseURI, PrintWriter out, Hash author, Archive archive) throws IOException {
|
||||
out.write("<tr><td colspan=\"3\">Profile for ");
|
||||
PetName pn = user.getPetNameDB().getByLocation(author.toBase64());
|
||||
String name = null;
|
||||
BlogInfo info = archive.getBlogInfo(author);
|
||||
if (pn != null) {
|
||||
out.write(pn.getName());
|
||||
name = null;
|
||||
if (info != null)
|
||||
name = info.getProperty(BlogInfo.NAME);
|
||||
|
||||
if ( (name == null) || (name.trim().length() <= 0) )
|
||||
name = author.toBase64().substring(0, 6);
|
||||
|
||||
out.write(" (" + name + ")");
|
||||
} else {
|
||||
if (info != null)
|
||||
name = info.getProperty(BlogInfo.NAME);
|
||||
|
||||
if ( (name == null) || (name.trim().length() <= 0) )
|
||||
name = author.toBase64().substring(0, 6);
|
||||
out.write(name);
|
||||
}
|
||||
out.write("</a>");
|
||||
if (info != null)
|
||||
out.write(" [edition " + info.getEdition() + "]");
|
||||
out.write("<br />\n");
|
||||
out.write("<a href=\"" + getControlTarget() + "?" + ThreadedHTMLRenderer.PARAM_AUTHOR
|
||||
+ '=' + author.toBase64() + "&" + ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR + "=true&\""
|
||||
+ " title=\"View '" + HTMLRenderer.sanitizeTagParam(name) + "'s blog\">View their blog</a> or ");
|
||||
out.write("<a href=\"" + getControlTarget() + "?" + ThreadedHTMLRenderer.PARAM_AUTHOR
|
||||
+ '=' + author.toBase64() + "&\">threads they have participated in</a>\n");
|
||||
out.write("</td></tr>\n");
|
||||
|
||||
out.write("<tr><td colspan=\"3\"><hr /></td></tr>\n");
|
||||
if (pn == null) {
|
||||
out.write("<tr><td colspan=\"3\">Not currently bookmarked. Add them to your ");
|
||||
String addFav = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_FAVORITE,
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
String addIgnore = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_IGNORE,
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
out.write("<a href=\"" + addFav + "\" title=\"Threads by favorite authors are shown specially\">favorites</a> or ");
|
||||
out.write("<a href=\"" + addIgnore + "\" title=\"Threads by ignored authors are hidden from view\">ignored</a> ");
|
||||
out.write("</td></tr>\n");
|
||||
} else if (pn.isMember(FilteredThreadIndex.GROUP_IGNORE)) {
|
||||
out.write("<tr><td colspan=\"3\">Currently ignored - threads they create are hidden.</td></tr>\n");
|
||||
String remIgnore = getRemoveFromGroupLink(user, pn.getName(), FilteredThreadIndex.GROUP_IGNORE,
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
out.write("<tr><td colspan=\"3\"><a href=\"" + remIgnore + "\">Unignore " + pn.getName() + "</a></td></tr>\n");
|
||||
String remCompletely = getRemoveFromGroupLink(user, pn.getName(), "",
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
out.write("<tr><td colspan=\"3\"><a href=\"" + remCompletely + "\">Forget about " + pn.getName() + " entirely</a></td></tr>\n");
|
||||
} else if (pn.isMember(FilteredThreadIndex.GROUP_FAVORITE)) {
|
||||
out.write("<tr><td colspan=\"3\">Currently marked as a favorite author - threads they participate in " +
|
||||
"are highlighted.</td></tr>\n");
|
||||
String remIgnore = getRemoveFromGroupLink(user, pn.getName(), FilteredThreadIndex.GROUP_FAVORITE,
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
out.write("<tr><td colspan=\"3\"><a href=\"" + remIgnore + "\">Remove " + pn.getName() + " from the list of favorite authors</a></td></tr>\n");
|
||||
String addIgnore = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_IGNORE,
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
out.write("<tr><td colspan=\"3\"><a href=\"" + addIgnore + "\" title=\"Threads by ignored authors are hidden from view\">Ignore the author</a></td></tr>");
|
||||
String remCompletely = getRemoveFromGroupLink(user, pn.getName(), "",
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
out.write("<tr><td colspan=\"3\"><a href=\"" + remCompletely + "\">Forget about " + pn.getName() + " entirely</a></td></tr>\n");
|
||||
} else {
|
||||
out.write("<tr><td colspan=\"3\">Currently bookmarked. Add them to your ");
|
||||
String addFav = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_FAVORITE,
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
String addIgnore = getAddToGroupLink(user, author, FilteredThreadIndex.GROUP_IGNORE,
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
out.write("<a href=\"" + addFav + "\" title=\"Threads by favorite authors are shown specially\">favorites</a> or ");
|
||||
out.write("<a href=\"" + addIgnore + "\" title=\"Threads by ignored authors are hidden from view\">ignored</a> list</td></tr>");
|
||||
String remCompletely = getRemoveFromGroupLink(user, pn.getName(), "",
|
||||
baseURI, "", "", "", "", "", author.toBase64());
|
||||
out.write("<tr><td colspan=\"3\"><a href=\"" + remCompletely + "\">Forget about " + pn.getName() + " entirely</a></td></tr>\n");
|
||||
}
|
||||
|
||||
if (info != null) {
|
||||
String descr = info.getProperty(BlogInfo.DESCRIPTION);
|
||||
if ( (descr != null) && (descr.trim().length() > 0) )
|
||||
out.write("<tr><td colspan=\"3\">Account description: " + HTMLRenderer.sanitizeString(descr) + "</td></tr>\n");
|
||||
|
||||
String contactURL = info.getProperty(BlogInfo.CONTACT_URL);
|
||||
if ( (contactURL != null) && (contactURL.trim().length() > 0) )
|
||||
out.write("<tr><td colspan=\"3\">Contact information: "
|
||||
+ HTMLRenderer.sanitizeString(contactURL) + "</td></tr>\n");
|
||||
|
||||
String props[] = info.getProperties();
|
||||
int altCount = 0;
|
||||
if (props != null)
|
||||
for (int i = 0; i < props.length; i++)
|
||||
if (!BlogInfo.NAME.equals(props[i]) &&
|
||||
!BlogInfo.DESCRIPTION.equals(props[i]) &&
|
||||
!BlogInfo.EDITION.equals(props[i]) &&
|
||||
!BlogInfo.OWNER_KEY.equals(props[i]) &&
|
||||
!BlogInfo.POSTERS.equals(props[i]) &&
|
||||
!BlogInfo.SIGNATURE.equals(props[i]) &&
|
||||
!BlogInfo.CONTACT_URL.equals(props[i]))
|
||||
altCount++;
|
||||
if (altCount > 0) {
|
||||
for (int i = 0; i < props.length; i++) {
|
||||
if (!BlogInfo.NAME.equals(props[i]) &&
|
||||
!BlogInfo.DESCRIPTION.equals(props[i]) &&
|
||||
!BlogInfo.EDITION.equals(props[i]) &&
|
||||
!BlogInfo.OWNER_KEY.equals(props[i]) &&
|
||||
!BlogInfo.POSTERS.equals(props[i]) &&
|
||||
!BlogInfo.SIGNATURE.equals(props[i]) &&
|
||||
!BlogInfo.CONTACT_URL.equals(props[i])) {
|
||||
out.write("<tr><td colspan=\"3\">");
|
||||
out.write(HTMLRenderer.sanitizeString(props[i]) + ": "
|
||||
+ HTMLRenderer.sanitizeString(info.getProperty(props[i])));
|
||||
out.write("</td></tr>\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
protected String getTitle() { return "Syndie :: Configure blog"; }
|
||||
}
|
@ -59,7 +59,7 @@ public class ProfileServlet extends BaseServlet {
|
||||
out.write("<form action=\"" + baseURI + "\" method=\"POST\">\n");
|
||||
writeAuthActionFields(out);
|
||||
// now add the form to update
|
||||
out.write("<tr><td colspan=\"3\">Your profile</td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">Your profile (<a href=\"configblog.jsp\">configure your blog</a>)</td></tr>\n");
|
||||
out.write("<tr><td colspan=\"3\">Name: <input type=\"text\" name=\""
|
||||
+ ThreadedHTMLRenderer.PARAM_PROFILE_NAME + "\" value=\""
|
||||
+ HTMLRenderer.sanitizeTagParam(info.getProperty(BlogInfo.NAME)) + "\"></td></tr>\n");
|
||||
|
478
apps/syndie/java/src/net/i2p/syndie/web/ViewBlogServlet.java
Normal file
478
apps/syndie/java/src/net/i2p/syndie/web/ViewBlogServlet.java
Normal file
@ -0,0 +1,478 @@
|
||||
package net.i2p.syndie.web;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import net.i2p.I2PAppContext;
|
||||
import net.i2p.client.naming.*;
|
||||
import net.i2p.data.*;
|
||||
import net.i2p.syndie.*;
|
||||
import net.i2p.syndie.data.*;
|
||||
import net.i2p.syndie.sml.*;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.Log;
|
||||
|
||||
/**
|
||||
* Render the appropriate posts for the current blog, using any blog info data available
|
||||
*
|
||||
*/
|
||||
public class ViewBlogServlet extends BaseServlet {
|
||||
public static final String PARAM_OFFSET = "offset";
|
||||
/** $blogHash */
|
||||
public static final String PARAM_BLOG = "blog";
|
||||
/** $blogHash/$entryId */
|
||||
public static final String PARAM_ENTRY = "entry";
|
||||
/** tag,tag,tag */
|
||||
public static final String PARAM_TAG = "tag";
|
||||
/** $blogHash/$entryId/$attachmentId */
|
||||
public static final String PARAM_ATTACHMENT = "attachment";
|
||||
|
||||
public void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
req.setCharacterEncoding("UTF-8");
|
||||
String attachment = req.getParameter(PARAM_ATTACHMENT);
|
||||
if (attachment != null) {
|
||||
// if they requested an attachment, serve it up to 'em
|
||||
if (renderAttachment(req, resp, attachment))
|
||||
return;
|
||||
}
|
||||
//todo: take care of logo requests, etc
|
||||
super.service(req, resp);
|
||||
}
|
||||
|
||||
protected void render(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index) throws ServletException, IOException {
|
||||
Archive archive = BlogManager.instance().getArchive();
|
||||
|
||||
Hash blog = null;
|
||||
String name = req.getParameter(PARAM_BLOG);
|
||||
if ( (name == null) || (name.trim().length() <= 0) ) {
|
||||
blog = user.getBlog();
|
||||
} else {
|
||||
byte val[] = Base64.decode(name);
|
||||
if ( (val != null) && (val.length == Hash.HASH_LENGTH) )
|
||||
blog = new Hash(val);
|
||||
}
|
||||
|
||||
BlogInfo info = null;
|
||||
if (blog != null)
|
||||
info = archive.getBlogInfo(blog);
|
||||
|
||||
int offset = 0;
|
||||
String off = req.getParameter(PARAM_OFFSET);
|
||||
if (off != null) try { offset = Integer.parseInt(off); } catch (NumberFormatException nfe) {}
|
||||
|
||||
List posts = getPosts(user, archive, info, req, index);
|
||||
render(user, req, out, archive, info, posts, offset);
|
||||
}
|
||||
|
||||
private BlogURI getEntry(HttpServletRequest req) {
|
||||
String param = req.getParameter(PARAM_ENTRY);
|
||||
if (param != null)
|
||||
return new BlogURI("blog://" + param);
|
||||
return null;
|
||||
}
|
||||
|
||||
private List getPosts(User user, Archive archive, BlogInfo info, HttpServletRequest req, ThreadIndex index) {
|
||||
List rv = new ArrayList(1);
|
||||
if (info == null) return rv;
|
||||
|
||||
ArchiveIndex aindex = archive.getIndex();
|
||||
|
||||
BlogURI uri = getEntry(req);
|
||||
if (uri != null) {
|
||||
rv.add(uri);
|
||||
return rv;
|
||||
}
|
||||
|
||||
aindex.selectMatchesOrderByEntryId(rv, info.getKey().calculateHash(), null);
|
||||
|
||||
// lets filter out any posts that are not roots
|
||||
for (int i = 0; i < rv.size(); i++) {
|
||||
BlogURI curURI = (BlogURI)rv.get(i);
|
||||
ThreadNode node = index.getNode(curURI);
|
||||
if ( (node != null) && (node.getParent() == null) ) {
|
||||
// ok, its a root
|
||||
Collection tags = node.getTags();
|
||||
if ( (tags != null) && (tags.contains(BlogInfoData.TAG)) ) {
|
||||
// skip this, as its an info post
|
||||
rv.remove(i);
|
||||
i--;
|
||||
}
|
||||
} else {
|
||||
rv.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
private void render(User user, HttpServletRequest req, PrintWriter out, Archive archive, BlogInfo info, List posts, int offset) throws IOException {
|
||||
String title = null;
|
||||
String desc = null;
|
||||
BlogInfoData data = null;
|
||||
if (info != null) {
|
||||
title = info.getProperty(BlogInfo.NAME);
|
||||
desc = info.getProperty(BlogInfo.DESCRIPTION);
|
||||
String dataURI = info.getProperty(BlogInfo.SUMMARY_ENTRY_ID);
|
||||
if (dataURI != null) {
|
||||
EntryContainer entry = archive.getEntry(new BlogURI(dataURI));
|
||||
if (entry != null) {
|
||||
data = new BlogInfoData();
|
||||
try {
|
||||
data.load(entry);
|
||||
} catch (IOException ioe) {
|
||||
data = null;
|
||||
if (_log.shouldLog(Log.WARN))
|
||||
_log.warn("Error loading the blog info data from " + dataURI, ioe);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
String pageTitle = "Syndie :: Blogs" + (desc != null ? " :: " + desc : "");
|
||||
if (title != null) pageTitle = pageTitle + " (" + title + ")";
|
||||
pageTitle = HTMLRenderer.sanitizeString(pageTitle);
|
||||
out.write("<html>\n<head>\n<title>" + pageTitle + "</title>\n");
|
||||
out.write("<style>");
|
||||
renderStyle(out, info, data, req);
|
||||
out.write("</style></head>");
|
||||
renderHeader(user, req, out, info, data, title, desc);
|
||||
renderReferences(out, info, data);
|
||||
renderBody(user, out, info, data, posts, offset, archive, req);
|
||||
out.write("</body></html>\n");
|
||||
}
|
||||
private void renderStyle(PrintWriter out, BlogInfo info, BlogInfoData data, HttpServletRequest req) throws IOException {
|
||||
// modify it based on data.getStyleOverrides()...
|
||||
out.write(CSS);
|
||||
Reader css = null;
|
||||
try {
|
||||
InputStream in = req.getSession().getServletContext().getResourceAsStream("/syndie.css");
|
||||
if (in != null) {
|
||||
css = new InputStreamReader(in, "UTF-8");
|
||||
char buf[] = new char[1024];
|
||||
int read = 0;
|
||||
while ( (read = css.read(buf)) != -1)
|
||||
out.write(buf, 0, read);
|
||||
}
|
||||
} finally {
|
||||
if (css != null)
|
||||
css.close();
|
||||
}
|
||||
String content = FileUtil.readTextFile("./docs/syndie_standard.css", -1, true);
|
||||
if (content != null) out.write(content);
|
||||
}
|
||||
|
||||
private void renderHeader(User user, HttpServletRequest req, PrintWriter out, BlogInfo info, BlogInfoData data, String title, String desc) throws IOException {
|
||||
out.write("<body class=\"syndieBlog\">\n<span style=\"display: none\">" +
|
||||
"<a href=\"#content\" title=\"Skip to the blog content\">Content</a></span>\n");
|
||||
renderNavBar(user, req, out);
|
||||
out.write("<div class=\"syndieBlogHeader\">\n");
|
||||
if (data != null) {
|
||||
if (data.isLogoSpecified()) {
|
||||
out.write("<img src=\"logo.png\" alt=\"\" />\n");
|
||||
}
|
||||
}
|
||||
String name = desc;
|
||||
if ( (name == null) || (name.trim().length() <= 0) )
|
||||
name = title;
|
||||
if ( ( (name == null) || (name.trim().length() <= 0) ) && (info != null) )
|
||||
name = info.getKey().calculateHash().toBase64();
|
||||
if (name != null) {
|
||||
String url = "blog.jsp?" + (info != null ? PARAM_BLOG + "=" + info.getKey().calculateHash().toBase64() : "");
|
||||
out.write("<b><a href=\"" + url + "\" title=\"Go to the blog root\">"
|
||||
+ HTMLRenderer.sanitizeString(name) + "</a></b>");
|
||||
}
|
||||
out.write("</div>\n");
|
||||
}
|
||||
|
||||
private static final String DEFAULT_GROUP_NAME = "References";
|
||||
private void renderReferences(PrintWriter out, BlogInfo info, BlogInfoData data) throws IOException {
|
||||
out.write("<div class=\"syndieBlogLinks\">\n");
|
||||
if (data != null) {
|
||||
for (int i = 0; i < data.getReferenceGroupCount(); i++) {
|
||||
List group = data.getReferenceGroup(i);
|
||||
if (group.size() <= 0) continue;
|
||||
PetName pn = (PetName)group.get(0);
|
||||
String name = null;
|
||||
if (pn.getGroupCount() <= 0)
|
||||
name = DEFAULT_GROUP_NAME;
|
||||
else
|
||||
name = HTMLRenderer.sanitizeString(pn.getGroup(0));
|
||||
out.write("<!-- group " + name + " -->\n");
|
||||
out.write("<div class=\"syndieBlogLinkGroup\">\n");
|
||||
out.write("<span class=\"syndieBlogLinkGroupName\">" + name + "</span>\n");
|
||||
out.write("<ul>\n");
|
||||
for (int j = 0; j < group.size(); j++) {
|
||||
pn = (PetName)group.get(j);
|
||||
out.write("<li>" + renderLink(pn) + "</li>\n");
|
||||
}
|
||||
out.write("</ul>\n</div>\n<!-- end " + name + " -->\n");
|
||||
}
|
||||
}
|
||||
out.write("<div class=\"syndieBlogLinkGroup\">\n");
|
||||
out.write("<span class=\"syndieBlogLinkGroupName\">Custom links</span>\n");
|
||||
out.write("<ul><li><a href=\"\">are not yet implemented</a></li><li><a href=\"\">but are coming soon</a></li></ul>\n");
|
||||
out.write("</div><!-- end fake group -->");
|
||||
out.write("<div class=\"syndieBlogMeta\">");
|
||||
out.write("Secured by <a href=\"http://syndie.i2p.net/\">Syndie</a>");
|
||||
out.write("</div>\n");
|
||||
out.write("</div><!-- end syndieBlogLinks -->\n\n");
|
||||
}
|
||||
|
||||
private String renderLink(PetName pn) {
|
||||
return "<a href=\"\" title=\"go somewhere\">" + HTMLRenderer.sanitizeString(pn.getName()) + "</a>";
|
||||
}
|
||||
|
||||
private static final int POSTS_PER_PAGE = 5;
|
||||
private void renderBody(User user, PrintWriter out, BlogInfo info, BlogInfoData data, List posts, int offset, Archive archive, HttpServletRequest req) throws IOException {
|
||||
out.write("<div class=\"syndieBlogBody\">\n<span style=\"display: none\" id=\"content\"></span>\n\n");
|
||||
if (info == null) {
|
||||
out.write("No blog specified\n");
|
||||
return;
|
||||
}
|
||||
|
||||
BlogRenderer renderer = new BlogRenderer(_context, info, data);
|
||||
|
||||
if ( (posts.size() == 1) && (req.getParameter(PARAM_ENTRY) != null) ) {
|
||||
BlogURI uri = (BlogURI)posts.get(0);
|
||||
EntryContainer entry = archive.getEntry(uri);
|
||||
renderer.render(user, archive, entry, out, false, true);
|
||||
renderComments(user, out, info, data, entry, archive, renderer);
|
||||
} else {
|
||||
for (int i = offset; i < posts.size() && i < offset + POSTS_PER_PAGE; i++) {
|
||||
BlogURI uri = (BlogURI)posts.get(i);
|
||||
EntryContainer entry = archive.getEntry(uri);
|
||||
renderer.render(user, archive, entry, out, true, true);
|
||||
}
|
||||
|
||||
renderNav(out, info, data, posts, offset, archive, req);
|
||||
}
|
||||
|
||||
out.write("</div><!-- end syndieBlogBody -->\n");
|
||||
}
|
||||
|
||||
private void renderComments(User user, PrintWriter out, BlogInfo info, BlogInfoData data, EntryContainer entry,
|
||||
Archive archive, BlogRenderer renderer) throws IOException {
|
||||
ArchiveIndex index = archive.getIndex();
|
||||
out.write("<div class=\"syndieBlogComments\">\n");
|
||||
renderComments(user, out, entry.getURI(), archive, index, renderer);
|
||||
out.write("</div>\n");
|
||||
}
|
||||
private void renderComments(User user, PrintWriter out, BlogURI parentURI, Archive archive, ArchiveIndex index, BlogRenderer renderer) throws IOException {
|
||||
List replies = index.getReplies(parentURI);
|
||||
if (replies.size() > 0) {
|
||||
out.write("<ul>\n");
|
||||
for (int i = 0; i < replies.size(); i++) {
|
||||
BlogURI uri = (BlogURI)replies.get(i);
|
||||
out.write("<li>");
|
||||
if (!shouldIgnore(user, uri)) {
|
||||
EntryContainer cur = archive.getEntry(uri);
|
||||
renderer.render(user, archive, cur, out, false, true);
|
||||
// recurse
|
||||
renderComments(user, out, uri, archive, index, renderer);
|
||||
}
|
||||
out.write("</li>\n");
|
||||
}
|
||||
out.write("</ul>\n");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldIgnore(User user, BlogURI uri) {
|
||||
PetName pn = user.getPetNameDB().getByLocation(uri.getKeyHash().toBase64());
|
||||
return ( (pn != null) && pn.isMember(FilteredThreadIndex.GROUP_IGNORE));
|
||||
}
|
||||
|
||||
private void renderNav(PrintWriter out, BlogInfo info, BlogInfoData data, List posts, int offset, Archive archive, HttpServletRequest req) throws IOException {
|
||||
out.write("<div class=\"syndieBlogNav\"><hr style=\"display: none\" />\n");
|
||||
String uri = req.getRequestURI() + "?";
|
||||
if (info != null)
|
||||
uri = uri + PARAM_BLOG + "=" + info.getKey().calculateHash().toBase64() + "&";
|
||||
if (offset + POSTS_PER_PAGE >= posts.size())
|
||||
out.write(POSTS_PER_PAGE + " more older entries");
|
||||
else
|
||||
out.write("<a href=\"" + uri + "offset=" + (offset+POSTS_PER_PAGE) + "\">"
|
||||
+ POSTS_PER_PAGE + " older entries</a>");
|
||||
out.write(" | ");
|
||||
if (offset <= 0)
|
||||
out.write(POSTS_PER_PAGE + " more recent entries");
|
||||
else
|
||||
out.write("<a href=\"" + uri + "offset=" +
|
||||
(offset >= POSTS_PER_PAGE ? offset-POSTS_PER_PAGE : 0)
|
||||
+ "\">" + POSTS_PER_PAGE + " more recent entries</a>");
|
||||
|
||||
out.write("</div><!-- end syndieBlogNav -->\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* render the attachment to the browser, using the appropriate mime types, etc
|
||||
* @param attachment formatted as $blogHash/$entryId/$attachmentId
|
||||
* @return true if rendered
|
||||
*/
|
||||
private boolean renderAttachment(HttpServletRequest req, HttpServletResponse resp, String attachment) throws ServletException, IOException {
|
||||
int split = attachment.lastIndexOf('/');
|
||||
if (split <= 0)
|
||||
return false;
|
||||
BlogURI uri = new BlogURI("blog://" + attachment.substring(0, split));
|
||||
try {
|
||||
int attachmentId = Integer.parseInt(attachment.substring(split+1));
|
||||
if (attachmentId < 0) return false;
|
||||
EntryContainer entry = BlogManager.instance().getArchive().getEntry(uri);
|
||||
if (entry == null) {
|
||||
System.out.println("Could not render the attachment [" + uri + "] / " + attachmentId);
|
||||
return false;
|
||||
}
|
||||
Attachment attachments[] = entry.getAttachments();
|
||||
if (attachmentId >= attachments.length) {
|
||||
System.out.println("Out of range attachment on " + uri + ": " + attachmentId);
|
||||
return false;
|
||||
}
|
||||
|
||||
resp.setContentType(ArchiveViewerBean.getAttachmentContentType(attachments[attachmentId]));
|
||||
boolean inline = ArchiveViewerBean.getAttachmentShouldShowInline(attachments[attachmentId]);
|
||||
String filename = ArchiveViewerBean.getAttachmentFilename(attachments[attachmentId]);
|
||||
if (inline)
|
||||
resp.setHeader("Content-Disposition", "inline; filename=\"" + filename + "\"");
|
||||
else
|
||||
resp.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
|
||||
int len = ArchiveViewerBean.getAttachmentContentLength(attachments[attachmentId]);
|
||||
if (len >= 0)
|
||||
resp.setContentLength(len);
|
||||
ArchiveViewerBean.renderAttachment(attachments[attachmentId], resp.getOutputStream());
|
||||
return true;
|
||||
} catch (NumberFormatException nfe) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static final String CSS =
|
||||
"<style>\n" +
|
||||
"body {\n" +
|
||||
" margin: 0px;\n" +
|
||||
" padding: 0px;\n" +
|
||||
" font-family: Arial, Helvetica, sans-serif;\n" +
|
||||
"}\n" +
|
||||
".syndieBlog {\n" +
|
||||
" font-size: 100%;\n" +
|
||||
" margin: 0px;\n" +
|
||||
" border: 0px;\n" +
|
||||
" padding: 0px;\n" +
|
||||
" border-width: 0px;\n" +
|
||||
" border-spacing: 0px;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogTopNav {\n" +
|
||||
" width: 100%;\n" +
|
||||
" height: 20px;\n" +
|
||||
" background-color: #BBBBBB;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogTopNavUser {\n" +
|
||||
" text-align: left;\n" +
|
||||
" float: left;\n" +
|
||||
" display: inline;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogTopNavAdmin {\n" +
|
||||
" text-align: left;\n" +
|
||||
" float: right;\n" +
|
||||
" display: inline;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogHeader {\n" +
|
||||
" width: 100%;\n" +
|
||||
" height: 50px;\n" +
|
||||
" font-size: 120%;\n" +
|
||||
" background-color: black;\n" +
|
||||
" color: white;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogLinks {\n" +
|
||||
" width: 200px;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogLinkGroup {\n" +
|
||||
" text-align: left;\n" +
|
||||
" font-size: 80%;\n" +
|
||||
" background-color: #DDD;\n" +
|
||||
" border: solid;\n" +
|
||||
" //border-width: 5px 5px 0px 5px;\n" +
|
||||
" //border-color: #FFFFFF;\n" +
|
||||
" border-width: 1px 1px 1px 1px;\n" +
|
||||
" border-color: #000;\n" +
|
||||
" margin-top: 5px;\n" +
|
||||
" margin-right: 5px;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogLinkGroup ul {\n" +
|
||||
" list-style: none;\n" +
|
||||
" margin-left: 0;\n" +
|
||||
" margin-top: 0;\n" +
|
||||
" margin-bottom: 0;\n" +
|
||||
" padding-left: 0;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogLinkGroup li {\n" +
|
||||
" margin: 0;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogLinkGroup li a {\n" +
|
||||
" display: block;\n" +
|
||||
" width: 100%;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogLinkGroupName {\n" +
|
||||
" font-size: 80%;\n" +
|
||||
" font-weight: bold;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogMeta {\n" +
|
||||
" text-align: left;\n" +
|
||||
" font-size: 80%;\n" +
|
||||
" background-color: #DDD;\n" +
|
||||
" border: solid;\n" +
|
||||
" border-width: 1px 1px 1px 1px;\n" +
|
||||
" border-color: #000;\n" +
|
||||
" width: 90%;\n" +
|
||||
" margin-top: 5px;\n" +
|
||||
" margin-right: 5px;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogBody {\n" +
|
||||
" position: absolute;\n" +
|
||||
" top: 70px;\n" +
|
||||
" left: 200px;\n" +
|
||||
" float: left;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogPost {\n" +
|
||||
" border: solid;\n" +
|
||||
" border-width: 1px 1px 1px 1px;\n" +
|
||||
" border-color: #000;\n" +
|
||||
" margin-top: 5px;\n" +
|
||||
" width: 100%;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogPostHeader {\n" +
|
||||
" background-color: #BBB;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogPostSubject {\n" +
|
||||
" text-align: left;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogPostFrom {\n" +
|
||||
" text-align: right;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogPostSummary {\n" +
|
||||
" background-color: #FFFFFF;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogPostDetails {\n" +
|
||||
" background-color: #DDD;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogNav {\n" +
|
||||
" text-align: center;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogComments {\n" +
|
||||
" border: none;\n" +
|
||||
" margin-top: 5px;\n" +
|
||||
" margin-left: 0px;\n" +
|
||||
" float: left;\n" +
|
||||
"}\n" +
|
||||
".syndieBlogComments ul {\n" +
|
||||
" list-style: none;\n" +
|
||||
" margin-left: 10;\n" +
|
||||
" padding-left: 0;\n" +
|
||||
"}\n";
|
||||
|
||||
protected String getTitle() { return "unused"; }
|
||||
protected void renderServletDetails(User user, HttpServletRequest req, PrintWriter out, ThreadIndex index,
|
||||
int threadOffset, BlogURI visibleEntry, Archive archive) throws IOException {
|
||||
throw new RuntimeException("unused");
|
||||
}
|
||||
}
|
@ -29,8 +29,9 @@ public class ViewBlogsServlet extends BaseServlet {
|
||||
if ( (lastPost > 0) && (dayBegin - 3*24*60*60*1000l >= lastPost) ) // last post was old 3 days ago
|
||||
daysAgo = (int)((dayBegin - lastPost + 24*60*60*1000l-1)/(24*60*60*1000l));
|
||||
daysAgo++;
|
||||
return getControlTarget() + "?" + ThreadedHTMLRenderer.PARAM_AUTHOR + '=' + blog.toBase64()
|
||||
+ '&' + ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR + "=true&daysBack=" + daysAgo;
|
||||
return "blog.jsp?" + ViewBlogServlet.PARAM_BLOG + "=" + blog.toBase64();
|
||||
//return getControlTarget() + "?" + ThreadedHTMLRenderer.PARAM_AUTHOR + '=' + blog.toBase64()
|
||||
// + '&' + ThreadedHTMLRenderer.PARAM_THREAD_AUTHOR + "=true&daysBack=" + daysAgo;
|
||||
}
|
||||
|
||||
private String getPostDate(long when) {
|
||||
|
@ -69,6 +69,16 @@
|
||||
<servlet-class>net.i2p.syndie.web.ViewBlogsServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>net.i2p.syndie.web.BlogConfigServlet</servlet-name>
|
||||
<servlet-class>net.i2p.syndie.web.BlogConfigServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>net.i2p.syndie.web.ViewBlogServlet</servlet-name>
|
||||
<servlet-class>net.i2p.syndie.web.ViewBlogServlet</servlet-class>
|
||||
</servlet>
|
||||
|
||||
<servlet>
|
||||
<servlet-name>net.i2p.syndie.UpdaterServlet</servlet-name>
|
||||
<servlet-class>net.i2p.syndie.UpdaterServlet</servlet-class>
|
||||
@ -135,6 +145,14 @@
|
||||
<servlet-name>net.i2p.syndie.web.ViewBlogsServlet</servlet-name>
|
||||
<url-pattern>/blogs.jsp</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>net.i2p.syndie.web.BlogConfigServlet</servlet-name>
|
||||
<url-pattern>/configblog.jsp</url-pattern>
|
||||
</servlet-mapping>
|
||||
<servlet-mapping>
|
||||
<servlet-name>net.i2p.syndie.web.ViewBlogServlet</servlet-name>
|
||||
<url-pattern>/blog.jsp</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<session-config>
|
||||
<session-timeout>
|
||||
|
@ -1,4 +1,8 @@
|
||||
$Id: history.txt,v 1.377 2006/01/01 12:23:29 jrandom Exp $
|
||||
$Id: history.txt,v 1.378 2006/01/04 21:48:17 jrandom Exp $
|
||||
|
||||
2006-01-08 jrandom
|
||||
* First pass of the new blog interface, though without much of the useful
|
||||
customization features (coming soon)
|
||||
|
||||
2006-01-04 jrandom
|
||||
* Rather than profile individual tunnels for throughput over their
|
||||
|
Reference in New Issue
Block a user