Merge branch 'next' into edit-wot-trust
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 6 Jan 2011 06:56:28 +0000 (07:56 +0100)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Thu, 6 Jan 2011 06:56:28 +0000 (07:56 +0100)
pom.xml
src/main/java/net/pterodactylus/sone/main/SonePlugin.java
src/main/java/net/pterodactylus/sone/template/PostAccessor.java
src/main/java/net/pterodactylus/sone/template/ReplyAccessor.java
src/main/java/net/pterodactylus/sone/text/FreenetLinkParser.java
src/main/resources/i18n/sone.en.properties
src/main/resources/static/css/sone.css
src/main/resources/templates/notify/newSoneNotification.html

diff --git a/pom.xml b/pom.xml
index 780ea82..fa77daa 100644 (file)
--- a/pom.xml
+++ b/pom.xml
@@ -2,7 +2,7 @@
        <modelVersion>4.0.0</modelVersion>
        <groupId>net.pterodactylus</groupId>
        <artifactId>sone</artifactId>
-       <version>0.3.6-2</version>
+       <version>0.3.6-3</version>
        <dependencies>
                <dependency>
                        <groupId>net.pterodactylus</groupId>
index 8182fa2..a809e8e 100644 (file)
@@ -78,7 +78,7 @@ public class SonePlugin implements FredPlugin, FredPluginL10n, FredPluginBaseL10
        }
 
        /** The version. */
-       public static final Version VERSION = new Version(0, 3, 6, 2);
+       public static final Version VERSION = new Version(0, 3, 6, 3);
 
        /** The logger. */
        private static final Logger logger = Logging.getLogger(SonePlugin.class);
index 495d805..d5dd406 100644 (file)
@@ -79,7 +79,10 @@ public class PostAccessor extends ReflectionAccessor {
                                return null;
                        }
                        try {
-                               return linkParser.parse(new StringReader(text));
+                               synchronized (linkParser) {
+                                       linkParser.setPostingSone(post.getSone());
+                                       return linkParser.parse(new StringReader(text));
+                               }
                        } catch (IOException ioe1) {
                                /* ignore. */
                        }
index 1ec4e04..715b87f 100644 (file)
@@ -72,7 +72,10 @@ public class ReplyAccessor extends ReflectionAccessor {
                } else if (member.equals("text")) {
                        String text = reply.getText();
                        try {
-                               return linkParser.parse(new StringReader(text));
+                               synchronized (linkParser) {
+                                       linkParser.setPostingSone(reply.getSone());
+                                       return linkParser.parse(new StringReader(text));
+                               }
                        } catch (IOException ioe1) {
                                /* ignore. */
                        }
index 1d7c6b7..24eac3b 100644 (file)
@@ -26,6 +26,7 @@ import java.util.logging.Logger;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import net.pterodactylus.sone.data.Sone;
 import net.pterodactylus.util.logging.Logging;
 import net.pterodactylus.util.template.TemplateFactory;
 
@@ -50,52 +51,31 @@ public class FreenetLinkParser implements Parser {
        private enum LinkType {
 
                /** Link is a KSK. */
-               KSK(true),
+               KSK,
 
                /** Link is a CHK. */
-               CHK(true),
+               CHK,
 
                /** Link is an SSK. */
-               SSK(true),
+               SSK,
 
                /** Link is a USK. */
-               USK(true),
+               USK,
 
                /** Link is HTTP. */
-               HTTP(false),
+               HTTP,
 
                /** Link is HTTPS. */
-               HTTPS(false);
-
-               /** Whether this link type links to freenet. */
-               private final boolean anonymous;
-
-               /**
-                * Creates a new link type.
-                *
-                * @param anonymous
-                *            {@code true} if this link type links to freenet,
-                *            {@code false} otherwise
-                */
-               private LinkType(boolean anonymous) {
-                       this.anonymous = anonymous;
-               }
-
-               /**
-                * Returns whether this link type links anonymously to within freenet.
-                *
-                * @return {@code true} if this link type links to within freenet,
-                *         {@code false} otherwise
-                */
-               public boolean isAnonymous() {
-                       return anonymous;
-               }
+               HTTPS;
 
        }
 
        /** The template factory. */
        private final TemplateFactory templateFactory;
 
+       /** The Sone that posted the currently parsed text. */
+       private Sone postingSone;
+
        /**
         * Creates a new freenet link parser.
         *
@@ -107,6 +87,22 @@ public class FreenetLinkParser implements Parser {
        }
 
        //
+       // ACCESSORS
+       //
+
+       /**
+        * Sets the Sone that posted the text that will be parsed in the next call
+        * to {@link #parse(Reader)}. You need to synchronize calling this method
+        * and {@link #parse(Reader)}!
+        *
+        * @param sone
+        *            The Sone that posted the text
+        */
+       public void setPostingSone(Sone sone) {
+               postingSone = sone;
+       }
+
+       //
        // PART METHODS
        //
 
@@ -114,7 +110,6 @@ public class FreenetLinkParser implements Parser {
         * {@inheritDoc}
         */
        @Override
-       @SuppressWarnings("null")
        public Part parse(Reader source) throws IOException {
                PartContainer parts = new PartContainer();
                BufferedReader bufferedReader = (source instanceof BufferedReader) ? (BufferedReader) source : new BufferedReader(source);
@@ -170,8 +165,29 @@ public class FreenetLinkParser implements Parser {
                                        String name = link;
                                        logger.log(Level.FINER, "Found link: %s", link);
                                        logger.log(Level.FINEST, "Next: %d, CHK: %d, SSK: %d, USK: %d", new Object[] { next, nextChk, nextSsk, nextUsk });
-                                       if (((linkType == LinkType.CHK) || (linkType == LinkType.SSK) || (linkType == LinkType.USK)) && (link.length() > 98) && (link.charAt(47) == ',') && (link.charAt(91) == ',') && (link.charAt(99) == '/')) {
-                                               name = link.substring(0, 47) + "…" + link.substring(99);
+                                       if (linkType == LinkType.KSK) {
+                                               name = link.substring(4);
+                                       } else if ((linkType == LinkType.CHK) || (linkType == LinkType.SSK) || (linkType == LinkType.USK)) {
+                                               if (name.indexOf('/') > -1) {
+                                                       if (!name.endsWith("/")) {
+                                                               name = name.substring(name.lastIndexOf('/') + 1);
+                                                       } else {
+                                                               if (name.indexOf('/') != name.lastIndexOf('/')) {
+                                                                       name = name.substring(name.lastIndexOf('/', name.lastIndexOf('/') - 1));
+                                                               } else {
+                                                                       /* shorten to 5 chars. */
+                                                                       name = name.substring(4, 9);
+                                                               }
+                                                       }
+                                               }
+                                               if (name.indexOf('?') > -1) {
+                                                       name = name.substring(0, name.indexOf('?'));
+                                               }
+                                               boolean fromPostingSone = false;
+                                               if ((linkType == LinkType.SSK) || (linkType == LinkType.USK)) {
+                                                       fromPostingSone = link.substring(4, 47).equals(postingSone.getId());
+                                               }
+                                               parts.add(fromPostingSone ? createTrustedFreenetLinkPart(link, name) : createFreenetLinkPart(link, name));
                                        } else if ((linkType == LinkType.HTTP) || (linkType == LinkType.HTTPS)) {
                                                name = link.substring(linkType == LinkType.HTTP ? 7 : 8);
                                                int firstSlash = name.indexOf('/');
@@ -185,9 +201,12 @@ public class FreenetLinkParser implements Parser {
                                                if (((name.indexOf('/') > -1) && (name.indexOf('.') < name.lastIndexOf('.', name.indexOf('/'))) || ((name.indexOf('/') == -1) && (name.indexOf('.') < name.lastIndexOf('.')))) && name.startsWith("www.")) {
                                                        name = name.substring(4);
                                                }
+                                               if (name.indexOf('?') > -1) {
+                                                       name = name.substring(0, name.indexOf('?'));
+                                               }
                                                link = "?_CHECKED_HTTP_=" + link;
+                                               parts.add(createInternetLinkPart(link, name));
                                        }
-                                       parts.add(createLinkPart(linkType.isAnonymous(), link, name));
                                        line = line.substring(nextSpace);
                                } else {
                                        parts.add(createPlainTextPart(line.substring(0, next + 4)));
@@ -214,19 +233,45 @@ public class FreenetLinkParser implements Parser {
        }
 
        /**
-        * Creates a new link part based on a template.
+        * Creates a new part based on a template that links to a site within the
+        * normal internet.
+        *
+        * @param link
+        *            The target of the link
+        * @param name
+        *            The name of the link
+        * @return The part that displays the link
+        */
+       private Part createInternetLinkPart(String link, String name) {
+               return new TemplatePart(templateFactory.createTemplate(new StringReader("<a class=\"internet\" href=\"/<% link|html>\" title=\"<% link|html>\"><% name|html></a>"))).set("link", link).set("name", name);
+       }
+
+       /**
+        * Creates a new part based on a template that links to a site within
+        * freenet.
+        *
+        * @param link
+        *            The target of the link
+        * @param name
+        *            The name of the link
+        * @return The part that displays the link
+        */
+       private Part createFreenetLinkPart(String link, String name) {
+               return new TemplatePart(templateFactory.createTemplate(new StringReader("<a class=\"freenet\" href=\"/<% link|html>\" title=\"<% link|html>\"><% name|html></a>"))).set("link", link).set("name", name);
+       }
+
+       /**
+        * Creates a new part based on a template that links to a page in the
+        * poster’s keyspace.
         *
-        * @param anonymous
-        *            {@code true} if this link points to within freenet,
-        *            {@code false} if it points to the internet
         * @param link
         *            The target of the link
         * @param name
         *            The name of the link
         * @return The part that displays the link
         */
-       private Part createLinkPart(boolean anonymous, String link, String name) {
-               return new TemplatePart(templateFactory.createTemplate(new StringReader("<a <%if !anonymous>class=\"internet\" <%/if>href=\"<% link|html>\"><% name|html></a>"))).set("anonymous", anonymous).set("link", "/" + link).set("name", name);
+       private Part createTrustedFreenetLinkPart(String link, String name) {
+               return new TemplatePart(templateFactory.createTemplate(new StringReader("<a class=\"freenet-trusted\" href=\"/<% link|html>\" title=\"<% link|html>\"><% name|html></a>"))).set("link", link).set("name", name);
        }
 
 }
index a4b2f7b..686ba65 100644 (file)
@@ -194,6 +194,7 @@ Notification.FirstStart.Text=This seems to be the first time you start Sone. To
 Notification.Startup.Text=Sone is currently starting up. It may take a while to retrieve all identities and Sones from the web of trust. If you are missing some elements, please be patient, they will probably reappear very soon.
 Notification.ConfigNotRead.Text=The configuration file “sone.properties” could not be read, probably because it was not saved correctly. This can happen on versions prior to Sone 0.3.3 and there is nothing you can do about it.
 Notification.Button.Dismiss=Dismiss
+Notification.NewSone.ShortText=New Sones have been discovered:
 Notification.NewSone.Text=New Sones have been discovered:
 Notification.NewPost.ShortText=New posts have been discovered.
 Notification.NewPost.Text=New posts have been discovered by the following Sones:
index f1a89db..d1f85a2 100644 (file)
@@ -53,6 +53,22 @@ textarea {
        color: rgb(255, 0, 0);
 }
 
+#sone a.internet:before {
+       content: '⚠ ';
+}
+
+#sone a.freenet:before {
+       content: '» ';
+}
+
+#sone a.freenet-trusted {
+       color: rgb(0, 128, 0);
+}
+
+#sone a.freenet-trusted:before {
+       content: '★ ';
+}
+
 #sone a img {
        border: none;
 }
index a13d686..ec715ae 100644 (file)
@@ -1,4 +1,8 @@
-<div class="text">
+<div class="short-text">
+       <%= Notification.NewSone.ShortText|l10n|html>
+       <a href="javascript:showNotificationDetails('<%notification.id|html>'); return false;"><%= Notification.ClickHereToRead|l10n|html></a>
+</div>
+<div class="text hidden">
        <%= Notification.NewSone.Text|l10n|html>
        <%foreach sones sone>
                <a href="viewSone.html?sone=<% sone.id|html>" title="<% sone.requestUri|html>"><% sone.niceName|html></a><%notlast>,<%/notlast><%last>.<%/last>