2006-02-15 jrandom

* Add in per-blog RSS feeds to Syndie
    * Upgraded sucker's ROME dependency to 0.8, bundling sucked enclosures
      with the posts, marking additional attachments as Media RSS enclosures
      (http://search.yahoo.com/mrss/), since RSS only supports one enclosure
      per item.
    * Don't allow the default syndie user to be set to something invalid if
      its in single user mode.
This commit is contained in:
jrandom
2006-02-15 13:36:28 +00:00
committed by zzz
parent 113fbc1df3
commit 687abd9427
12 changed files with 128 additions and 34 deletions

View File

@ -1 +1 @@
This is ROME 0.7 from http://rome.dev.java.net/, released under a BSD license
This is ROME 0.8 from http://rome.dev.java.net/, released under a BSD license

Binary file not shown.

BIN
apps/rome/rome-0.8.jar Normal file

Binary file not shown.

View File

@ -15,7 +15,7 @@
srcdir="./src"
debug="true" deprecation="on" source="1.3" target="1.3"
destdir="./build/obj"
classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../jdom/jdom.jar:../../rome/rome-0.7.jar" />
classpath="../../../core/java/build/i2p.jar:../../jetty/jettylib/org.mortbay.jetty.jar:../../jetty/jettylib/javax.servlet.jar:../../jdom/jdom.jar:../../rome/rome-0.8.jar" />
</target>
<target name="jar" depends="builddep, compile">
<jar destfile="./build/syndie.jar" basedir="./build/obj" includes="**/*.class">
@ -27,7 +27,7 @@
<jar destfile="./build/sucker.jar" basedir="./build/obj" includes="net/i2p/syndie/Sucker.class, net/i2p/syndie/SuckerFetchListener.class">
<manifest>
<attribute name="Main-Class" value="net.i2p.syndie.Sucker" />
<attribute name="Class-Path" value="i2p.jar jdom.jar rome-0.7.jar" />
<attribute name="Class-Path" value="i2p.jar jdom.jar rome-0.8.jar" />
</manifest>
</jar>
<ant target="war" />
@ -37,7 +37,7 @@
<delete dir="./tmpwar" />
<mkdir dir="./tmpwar" />
<copy file="../../jdom/jdom.jar" tofile="./tmpwar/jdom.jar" />
<copy file="../../rome/rome-0.7.jar" tofile="./tmpwar/rome-0.7.jar" />
<copy file="../../rome/rome-0.8.jar" tofile="./tmpwar/rome-0.8.jar" />
<war destfile="../syndie.war" webxml="../jsp/web-out.xml">
<fileset dir="../jsp/" includes="**/*" excludes=".nbintdb, web.xml, web-out.xml, web-fragment.xml, **/*.java, **/*.jsp" />
@ -113,7 +113,7 @@
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../../jetty/jettylib/ant.jar" />
<pathelement location="../../jdom/jdom.jar" />
<pathelement location="../../rome/rome-0.7.jar" />
<pathelement location="../../rome/rome-0.8.jar" />
<pathelement location="build/obj" />
<pathelement location="../../../core/java/build/i2p.jar" />
</classpath>
@ -136,7 +136,7 @@
<pathelement location="../../jetty/jettylib/org.mortbay.jetty.jar" />
<pathelement location="../../jetty/jettylib/javax.servlet.jar" />
<pathelement location="../../jdom/jdom.jar" />
<pathelement location="../../rome/rome-0.7.jar" />
<pathelement location="../../rome/rome-0.8.jar" />
<pathelement location="build/obj" />
<pathelement location="../../../core/java/build/i2p.jar" />
</classpath>

View File

@ -580,9 +580,42 @@ public class BlogManager {
return (user.getAuthenticated() && user.getAllowAccessRemote());
}
private boolean isOkDefaultUser(String defaultUser, String defaultPass) {
User t = new User(_context);
Hash userHash = _context.sha().calculateHash(DataHelper.getUTF8(defaultUser));
File userFile = new File(_userDir, Base64.encode(userHash.getData()));
if (userFile.exists()) {
Properties props = loadUserProps(userFile);
if (props == null) {
_log.error("Error reading the default user file: " + userFile);
return false;
}
String ok = t.login(defaultUser, defaultPass, props);
if (User.LOGIN_OK.equals(ok)) {
// ok, good enough
return true;
} else {
_log.error("Error logging into the default user, so configuration change rejected: " + ok);
return false;
}
} else {
_log.error("Not setting the default user to a nonexistant user [" + defaultUser + "]");
return false;
}
}
public void configure(String registrationPassword, String remotePassword, String adminPass, String defaultSelector,
String defaultProxyHost, int defaultProxyPort, boolean isSingleUser, Properties opts,
String defaultUser, String defaultPass) {
if ( (defaultUser == null) || (defaultUser.length() <= 0) )
defaultUser = getDefaultLogin();
if (defaultPass == null)
defaultPass = getDefaultPass();
// first make sure the default user is valid, if its single user
if (isSingleUser) {
if (!isOkDefaultUser(defaultUser, defaultPass))
return;
}
File cfg = getConfigFile();
Writer out = null;
try {
@ -600,10 +633,6 @@ public class BlogManager {
if (defaultProxyPort > 0)
out.write("syndie.defaultProxyPort="+defaultProxyPort + "\n");
if ( (defaultUser == null) || (defaultUser.length() <= 0) )
defaultUser = getDefaultLogin();
if (defaultPass == null)
defaultPass = getDefaultPass();
out.write("syndie.defaultSingleUserLogin="+defaultUser+"\n");
out.write("syndie.defaultSingleUserPass="+defaultPass+"\n");

View File

@ -18,6 +18,7 @@ import java.util.List;
import com.sun.syndication.feed.synd.SyndCategory;
import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEnclosure;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedInput;
@ -396,7 +397,27 @@ public class Sucker {
sml += "\n";
}
}
String source=e.getUri();
List enclosures = e.getEnclosures();
debugLog("Enclosures: " + enclosures.size());
for (int i = 0; i < enclosures.size(); i++) {
SyndEnclosure enc = (SyndEnclosure)enclosures.get(i);
String enclosureURL = enc.getUrl();
if (enclosureURL != null) {
if (!enclosureURL.startsWith("http://")) {
// e.g. postman's rss feed @ http://tracker.postman.i2p/rss.jsp has
// baseUrl = http://tracker.postman.i2p
// and enclosure URLs are /download.php?id=123&file=blah
if (enclosureURL.startsWith("/") || baseUrl.endsWith("/"))
enclosureURL = baseUrl + enclosureURL;
else
enclosureURL = baseUrl + '/' + enclosureURL;
}
fetchAttachment(enclosureURL, enc.getType()); // fetches and adds to our streams
}
}
String source=e.getLink(); //Uri();
if(source.indexOf("http")<0)
source=baseUrl+source;
sml += "[link schema=\"web\" location=\""+source+"\"]source[/link]\n";
@ -654,7 +675,8 @@ public class Sucker {
return null;
}
private void fetchAttachment(String link) {
private void fetchAttachment(String link) { fetchAttachment(link, null); }
private void fetchAttachment(String link, String suggestedMimeType) {
link=link.replaceAll("&amp;","&");
@ -684,16 +706,19 @@ public class Sucker {
get.fetch();
boolean ok = lsnr.waitForSuccess();
if (!ok) {
System.err.println("Unable to retrieve the url after " + numRetries + " tries.");
debugLog("Unable to retrieve the url [" + link + "] after " + numRetries + " tries.");
fetched.delete();
return;
}
tempFiles.add(fetched);
String filename=EepGet.suggestName(link);
String contentType = get.getContentType();
String contentType = suggestedMimeType;
if (contentType == null)
contentType = get.getContentType();
if(contentType==null)
contentType="text/plain";
debugLog("successful fetch of filename "+filename);
debugLog("successful fetch of filename "+filename + " suggested mime type [" + suggestedMimeType
+ "], fetched mime type [" + get.getContentType() + "], final type [" + contentType + "]");
if(fileNames==null) fileNames = new ArrayList();
if(fileTypes==null) fileTypes = new ArrayList();
if(fileStreams==null) fileStreams = new ArrayList();

View File

@ -158,11 +158,14 @@ public class BlogRenderer extends HTMLRenderer {
protected String getEntryURL() { return getEntryURL(_user != null ? _user.getShowImages() : true); }
protected String getEntryURL(boolean showImages) {
if (_entry == null) return "unknown";
return getEntryURL(_entry, _blog, showImages);
}
static String getEntryURL(EntryContainer entry, BlogInfo blog, boolean showImages) {
if (entry == null) return "unknown";
return "blog.jsp?"
+ ViewBlogServlet.PARAM_BLOG + "=" + _blog.getKey().calculateHash().toBase64() + "&amp;"
+ ViewBlogServlet.PARAM_BLOG + "=" + (blog != null ? blog.getKey().calculateHash().toBase64() : "") + "&amp;"
+ ViewBlogServlet.PARAM_ENTRY + "="
+ Base64.encode(_entry.getURI().getKeyHash().getData()) + '/' + _entry.getURI().getEntryId();
+ Base64.encode(entry.getURI().getKeyHash().getData()) + '/' + entry.getURI().getEntryId();
}
protected String getAttachmentURLBase() {

View File

@ -24,18 +24,18 @@ public class RSSRenderer extends HTMLRenderer {
public void render(User user, Archive archive, EntryContainer entry, String urlPrefix, Writer out) throws IOException {
if (entry == null) return;
prepare(user, archive, entry, entry.getEntry().getText(), out, RSS_EXCERPT_ONLY, false);
BlogInfo info = archive.getBlogInfo(entry.getURI());
out.write(" <item>\n");
out.write(" <title>" + sanitizeXML(sanitizeString((String)_headers.get(HEADER_SUBJECT))) + "</title>\n");
out.write(" <link>" + urlPrefix + sanitizeXML(getEntryURL()) + "</link>\n");
out.write(" <guid isPermalink=\"false\">" + urlPrefix + entry.getURI().toString() + "</guid>\n");
out.write(" <link>" + urlPrefix + sanitizeXML(BlogRenderer.getEntryURL(entry, info, true)) + "</link>\n");
out.write(" <guid isPermalink=\"false\">syndie://" + entry.getURI().toString() + "</guid>\n");
out.write(" <pubDate>" + getRFC822Date(entry.getURI().getEntryId()) + "</pubDate>\n");
PetName pn = user.getPetNameDB().getByLocation(entry.getURI().getKeyHash().toBase64());
String author = null;
if (pn != null)
author = pn.getName();
if (author == null) {
BlogInfo info = archive.getBlogInfo(entry.getURI());
if (info != null)
author = info.getProperty(BlogInfo.NAME);
}
@ -49,7 +49,7 @@ public class RSSRenderer extends HTMLRenderer {
out.write(" <description>" + sanitizeXML(_bodyBuffer.toString()) + "</description>\n");
//renderEnclosures(user, entry, urlPrefix, out);
renderEnclosures(user, entry, urlPrefix, out);
out.write(" </item>\n");
}
@ -222,15 +222,27 @@ public class RSSRenderer extends HTMLRenderer {
}
private void renderEnclosures(User user, EntryContainer entry, String urlPrefix, Writer out) throws IOException {
int included = 0;
if (entry.getAttachments() != null) {
for (int i = 0; i < _entry.getAttachments().length; i++) {
Attachment a = _entry.getAttachments()[i];
out.write(" <enclosure url=\"" + urlPrefix + sanitizeXML(getAttachmentURL(i))
+ "\" length=\"" + a.getDataLength()
+ "\" type=\"" + sanitizeTagParam(a.getMimeType()) + "\" syndietype=\"attachment\" />\n");
out.write(" <media:content url=\"" + urlPrefix + sanitizeXML(getAttachmentURL(i))
+ "\" fileSize=\"" + a.getDataLength()
+ "\" type=\"" + sanitizeTagParam(a.getMimeType())
+ "\">");
// we can do neat stuff with Media RSS (http://search.yahoo.com/mrss) here, such as
// include descriptions, titles, keywords, thumbnails, etc
out.write(" </media:content>\n");
if (included == 0) // plain RSS enclosures can only have one enclosure per entry, unlike Media RSS
out.write(" <enclosure url=\"" + urlPrefix + sanitizeXML(getAttachmentURL(i))
+ "\" length=\"" + a.getDataLength()
+ "\" type=\"" + sanitizeTagParam(a.getMimeType()) + "\" syndietype=\"attachment\" />\n");
included++;
}
}
/*
if (_blogs.size() > 0) {
for (int i = 0; i < _blogs.size(); i++) {
Blog b = (Blog)_blogs.get(i);
@ -295,7 +307,8 @@ public class RSSRenderer extends HTMLRenderer {
if ( (inReplyTo != null) && (inReplyTo.trim().length() > 0) ) {
String url = getPageURL(sanitizeTagParam(inReplyTo));
out.write(" <enclosure url=\"" + urlPrefix + sanitizeXML(url) + "\" length=\"1\" type=\"text/html\" syndietype=\"parent\" />\n");
}
}
*/
}
public void receiveHeaderEnd() {}

View File

@ -60,7 +60,14 @@ public class RSSServlet extends HttpServlet {
if (count > 100) count = 100;
Archive archive = BlogManager.instance().getArchive();
FilteredThreadIndex index = new FilteredThreadIndex(user, archive, tagSet, null, false);
Set authors = new HashSet();
String reqAuth = req.getParameter(ThreadedHTMLRenderer.PARAM_AUTHOR);
if (reqAuth != null) {
byte v[] = Base64.decode(reqAuth);
if ( (v != null) && (v.length == Hash.HASH_LENGTH) )
authors.add(new Hash(v));
}
FilteredThreadIndex index = new FilteredThreadIndex(user, archive, tagSet, authors, false);
List entries = new ArrayList();
// depth first search of the most recent threads
for (int i = 0; i < count && i < index.getRootCount(); i++) {
@ -80,7 +87,7 @@ public class RSSServlet extends HttpServlet {
Writer out = resp.getWriter();
out.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n");
out.write("<rss version=\"2.0\">\n");
out.write("<rss version=\"2.0\" xmlns:media=\"http://search.yahoo.com/mrss/\">\n");
out.write(" <channel>\n");
out.write(" <title>Syndie feed</title>\n");
String page = urlPrefix;

View File

@ -162,6 +162,10 @@ public class ViewBlogServlet extends BaseServlet {
out.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
out.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n");
out.write("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n<head>\n<title>" + pageTitle + "</title>\n");
if (info != null)
out.write("<link href=\"rss.jsp?" + ThreadedHTMLRenderer.PARAM_AUTHOR + "="
+ info.getKey().calculateHash().toBase64()
+ "\" rel=\"alternate\" type=\"application/rss+xml\" >\n");
out.write("<style>");
renderStyle(out, info, data, req);
out.write("</style></head>");
@ -192,6 +196,7 @@ public class ViewBlogServlet extends BaseServlet {
}
public static String getLogoURL(Hash blog) {
if (blog == null) return "";
return "blog.jsp?" + PARAM_BLOG + "=" + blog.toBase64() + "&amp;"
+ PARAM_IMAGE + "=" + BlogInfoData.ATTACHMENT_LOGO;
}
@ -201,12 +206,15 @@ public class ViewBlogServlet extends BaseServlet {
"<a href=\"#content\" title=\"Skip to the blog content\">Content</a></span>\n");
renderNavBar(user, req, out);
out.write("<div class=\"syndieBlogHeader\">\n");
out.write("<img class=\"syndieBlogLogo\" src=\"" + getLogoURL(info.getKey().calculateHash()) + "\" alt=\"\" />\n");
Hash kh = null;
if ( (info != null) && (info.getKey() != null) )
kh = info.getKey().calculateHash();
out.write("<img class=\"syndieBlogLogo\" src=\"" + getLogoURL(kh) + "\" 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) || (name.trim().length() <= 0) ) && (info != null) && (kh != null) )
name = kh.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\">"

View File

@ -1,4 +1,13 @@
$Id: history.txt,v 1.396.2.19 2006/02/15 00:16:31 jrandom Exp $
$Id: history.txt,v 1.397 2006/02/15 00:33:17 jrandom Exp $
2006-02-15 jrandom
* Add in per-blog RSS feeds to Syndie
* Upgraded sucker's ROME dependency to 0.8, bundling sucked enclosures
with the posts, marking additional attachments as Media RSS enclosures
(http://search.yahoo.com/mrss/), since RSS only supports one enclosure
per item.
* Don't allow the default syndie user to be set to something invalid if
its in single user mode.
2006-02-15 jrandom
* Merged in the i2p_0_6_1_10_PRE branch to the trunk, so CVS HEAD is no

View File

@ -15,9 +15,9 @@ import net.i2p.CoreVersion;
*
*/
public class RouterVersion {
public final static String ID = "$Revision: 1.340.2.17 $ $Date: 2006/02/15 00:16:30 $";
public final static String ID = "$Revision: 1.341 $ $Date: 2006/02/15 00:33:33 $";
public final static String VERSION = "0.6.1.9";
public final static long BUILD = 25;
public final static long BUILD = 26;
public static void main(String args[]) {
System.out.println("I2P Router version: " + VERSION + "-" + BUILD);
System.out.println("Router ID: " + RouterVersion.ID);