diff options
author | Vitaly Takmazov | 2016-08-26 14:13:37 +0300 |
---|---|---|
committer | Vitaly Takmazov | 2016-08-30 10:52:51 +0300 |
commit | 6ea4235635c296991bbae3689d0b7dd735b17480 (patch) | |
tree | 33e5e931ea7638ef248c6413d41fcdc8bef0ee22 /juick-www | |
parent | 05b8019ab6dece881fb6a282c1bd50ff5ba22b69 (diff) |
pebble WIP
Diffstat (limited to 'juick-www')
-rw-r--r-- | juick-www/build.gradle | 1 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/Main.java | 8 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/PM.java | 67 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/PageTemplates.java | 98 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/RSS.java | 2 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/UserThread.java | 9 | ||||
-rw-r--r-- | juick-www/src/main/java/com/juick/www/Utils.java | 100 | ||||
-rw-r--r-- | juick-www/src/main/resources/layouts/content.html | 29 | ||||
-rw-r--r-- | juick-www/src/main/resources/views/partial/homecolumn.html | 6 | ||||
-rw-r--r-- | juick-www/src/main/resources/views/partial/navigation.html | 37 | ||||
-rw-r--r-- | juick-www/src/main/resources/views/partial/tags.html | 7 | ||||
-rw-r--r-- | juick-www/src/main/resources/views/pm_inbox.html | 36 |
12 files changed, 245 insertions, 155 deletions
diff --git a/juick-www/build.gradle b/juick-www/build.gradle index 27c3bc1a..891ee8f6 100644 --- a/juick-www/build.gradle +++ b/juick-www/build.gradle @@ -37,6 +37,7 @@ dependencies { compile 'net.coobird:thumbnailator:0.4.8' compile 'com.github.ooxi:serialized-php-parser:0.5.0' compile 'net.jodah:failsafe:0.9.2' + compile 'com.mitchellbosecke:pebble:2.2.2' providedCompile 'javax.servlet:javax.servlet-api:3.1.0' providedRuntime 'mysql:mysql-connector-java:5.1.39' } diff --git a/juick-www/src/main/java/com/juick/www/Main.java b/juick-www/src/main/java/com/juick/www/Main.java index c249995f..1e755ca3 100644 --- a/juick-www/src/main/java/com/juick/www/Main.java +++ b/juick-www/src/main/java/com/juick/www/Main.java @@ -21,6 +21,7 @@ import com.juick.server.UserQueries; import com.juick.xmpp.JID; import com.juick.xmpp.Stream; import com.juick.xmpp.StreamComponent; +import com.mitchellbosecke.pebble.error.PebbleException; import net.jodah.failsafe.Execution; import net.jodah.failsafe.RetryPolicy; import org.apache.commons.dbcp2.BasicDataSource; @@ -181,7 +182,12 @@ public class Main extends HttpServlet implements Stream.StreamListener { } else { switch (uri) { case "/pm/inbox": - pm.doGetInbox(sql, request, response, visitor); + try { + pm.doGetInbox(sql, request, response, visitor); + } catch (PebbleException e) { + log("pebble exception", e); + response.sendError(500); + } break; case "/pm/sent": pm.doGetSent(sql, request, response, visitor); diff --git a/juick-www/src/main/java/com/juick/www/PM.java b/juick-www/src/main/java/com/juick/www/PM.java index 9d7da65b..ac2cbb76 100644 --- a/juick-www/src/main/java/com/juick/www/PM.java +++ b/juick-www/src/main/java/com/juick/www/PM.java @@ -18,11 +18,14 @@ package com.juick.www; import com.juick.server.PMQueries; +import com.juick.server.TagQueries; import com.juick.server.UserQueries; import com.juick.xmpp.JID; import com.juick.xmpp.Message; import com.juick.xmpp.Stream; import com.juick.xmpp.extensions.JuickMessage; +import com.mitchellbosecke.pebble.error.PebbleException; +import com.mitchellbosecke.pebble.template.PebbleTemplate; import org.springframework.jdbc.core.JdbcTemplate; import javax.servlet.ServletException; @@ -30,7 +33,9 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -41,64 +46,20 @@ import java.util.logging.Logger; public class PM { private static final Logger logger = Logger.getLogger(PM.class.getName()); - protected void doGetInbox(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException { - /* - int paramBefore = 0; - String paramBeforeStr = request.getParameter("before"); - if (paramBeforeStr != null) { - try { - paramBefore = Integer.parseInt(paramBeforeStr); - } catch (NumberFormatException e) { - } - } - */ + protected void doGetInbox(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response, com.juick.User visitor) throws ServletException, IOException, PebbleException { String title = "PM: Inbox"; List<com.juick.Message> msgs = PMQueries.getLastPMInbox(sql, visitor.getUID()); response.setContentType("text/html; charset=UTF-8"); try (PrintWriter out = response.getWriter()) { - PageTemplates.pageHead(out, visitor, title, null); - PageTemplates.pageNavigation(out, visitor, null); - - out.println("<section id=\"content\">"); - - if (!msgs.isEmpty()) { - out.println("<ul id=\"private-messages\">"); - for (com.juick.Message msg : msgs) { - - String txt = PageTemplates.formatMessage(msg.getText()); - - out.println(" <li class=\"msg\">"); - out.println(" <div class=\"msg-cont\">"); - out.println(" <div class=\"msg-ts\"><a href=\"#\" onclick=\"return false\" title=\"" + PageTemplates.sdfSQL.format(msg.getDate()) + " GMT\">" + PageTemplates.formatDate(msg.TimeAgo, msg.getDate()) + "</a></div>"); - out.println(" <div class=\"msg-avatar\"><a href=\"/" + msg.getUser().getUName() + "/\"><img src=\"//i.juick.com/a/" + msg.getUser().getUID() + ".png\" alt=\"" + msg.getUser().getUName() + "\"/></a></div>"); - out.println(" <div class=\"msg-header\">@<a href=\"/" + msg.getUser().getUName() + "/\">" + msg.getUser().getUName() + "</a>:</div>"); - out.println(" <div class=\"msg-txt\">" + txt + "</div>"); - - out.println(" <form action=\"/pm/send\" method=\"POST\" enctype=\"multipart/form-data\"><input type=\"hidden\" name=\"uname\" value=\"" + msg.getUser().getUName() + "\"/>"); - out.println(" <div class=\"msg-comment\"><div class=\"ta-wrapper\"><textarea name=\"body\" rows=\"1\" class=\"replypm\" placeholder=\"Написать ответ\"></textarea></div></div>"); - out.println(" </form>"); - - out.println(" </div>"); - out.println(" </li>"); - } - out.println("</ul>"); - } - - /* - if (msgs.size() >= 20) { - String nextpage = "?before=" + msgs.get(msgs.size() - 1); - out.println("<p class=\"page\"><a href=\"" + nextpage + "\">Читать дальше →</a></p>"); - } - */ - - out.println("</section>"); - - PageTemplates.pageHomeColumn(out, sql, visitor); - - PageTemplates.pageFooter(request, out, visitor, false); - PageTemplates.pageEnd(out); + PebbleTemplate template = Utils.getEngine().getTemplate("views/pm_inbox.html"); + Map<String, Object> context = new HashMap<>(); + context.put("title", title); + context.put("visitor", visitor); + context.put("msgs", msgs); + context.put("tags", TagQueries.getPopularTags(sql)); + template.evaluate(out, context); } } @@ -142,7 +103,7 @@ public class PM { out.println("<ul>"); for (com.juick.Message msg : msgs) { - String txt = PageTemplates.formatMessage(msg.getText()); + String txt = Utils.formatMessage(msg.getText()); out.println(" <li class=\"msg\">"); out.println(" <div class=\"msg-avatar\"><img src=\"//i.juick.com/a/" + visitor.getUID() + ".png\"/></div>"); diff --git a/juick-www/src/main/java/com/juick/www/PageTemplates.java b/juick-www/src/main/java/com/juick/www/PageTemplates.java index 0cdf2184..c3b0d6f8 100644 --- a/juick-www/src/main/java/com/juick/www/PageTemplates.java +++ b/juick-www/src/main/java/com/juick/www/PageTemplates.java @@ -23,6 +23,7 @@ import com.juick.server.MessagesQueries; import com.juick.server.TagQueries; import com.juick.server.UserQueries; import org.apache.commons.lang3.StringEscapeUtils; +import com.mitchellbosecke.pebble.PebbleEngine; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.util.StringUtils; import ru.sape.Sape; @@ -279,99 +280,6 @@ public class PageTemplates { return replies + " ответов"; } } - private static Pattern regexLinks2 = Pattern.compile("((?<=\\s)|(?<=\\A))([\\[\\{]|<)((?:ht|f)tps?://(?:www\\.)?([^\\/\\s\\\"\\)\\!]+)/?(?:[^\\]\\}](?<!>))*)([\\]\\}]|>)"); - - public static String formatMessageCode(String msg) { - msg = msg.replaceAll("&", "&"); - msg = msg.replaceAll("<", "<"); - msg = msg.replaceAll(">", ">"); - - // http://juick.com/last?page=2 - // <a href="http://juick.com/last?page=2" rel="nofollow">http://juick.com/last?page=2</a> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A))((?:ht|f)tps?://(?:www\\.)?([^\\/\\s\\n\\\"]+)/?[^\\s\\n\\\"]*)", "$1<a href=\"$2\" rel=\"nofollow\">$2</a>"); - - // (http://juick.com/last?page=2) - // (<a href="http://juick.com/last?page=2" rel="nofollow">http://juick.com/last?page=2</a>) - Matcher m = regexLinks2.matcher(msg); - StringBuffer sb = new StringBuffer(); - while (m.find()) { - String url = m.group(3).replace(" ", "%20").replaceAll("\\s+", ""); - m.appendReplacement(sb, "$1$2<a href=\"" + url + "\" rel=\"nofollow\">" + url + "</a>$5"); - } - m.appendTail(sb); - msg = sb.toString(); - - return "<pre>" + msg + "</pre>"; - } - - public static String formatMessage(String msg) { - msg = msg.replaceAll("&", "&"); - msg = msg.replaceAll("<", "<"); - msg = msg.replaceAll(">", ">"); - - // -- - // — - msg = msg.replaceAll("((?<=\\s)|(?<=\\A))\\-\\-?((?=\\s)|(?=\\Z))", "$1—$2"); - - // http://juick.com/last?page=2 - // <a href="http://juick.com/last?page=2" rel="nofollow">juick.com</a> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A))((?:ht|f)tps?://(?:www\\.)?([^\\/\\s\\n\\\"]+)/?[^\\s\\n\\\"]*)", "$1<a href=\"$2\" rel=\"nofollow\">$3</a>"); - - // [link text][http://juick.com/last?page=2] - // <a href="http://juick.com/last?page=2" rel="nofollow">link text</a> - msg = msg.replaceAll("\\[([^\\]]+)\\]\\[((?:ht|f)tps?://[^\\]]+)\\]", "<a href=\"$2\" rel=\"nofollow\">$1</a>"); - msg = msg.replaceAll("\\[([^\\]]+)\\]\\(((?:ht|f)tps?://[^\\)]+)\\)", "<a href=\"$2\" rel=\"nofollow\">$1</a>"); - - // #12345 - // <a href="http://juick.com/12345">#12345</a> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A)|(?<=\\p{Punct}))#(\\d+)((?=\\s)|(?=\\Z)|(?=\\))|(?=\\.)|(?=\\,))", "$1<a href=\"http://juick.com/$2\">#$2</a>$3"); - - // #12345/65 - // <a href="http://juick.com/12345#65">#12345/65</a> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A)|(?<=\\p{Punct}))#(\\d+)/(\\d+)((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<a href=\"http://juick.com/$2#$3\">#$2/$3</a>$4"); - - // *bold* - // <b>bold</b> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A)|(?<=\\p{Punct}))\\*([^\\*\\n<>]+)\\*((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<b>$2</b>$3"); - - // /italic/ - // <i>italic</i> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A))/([^\\/\\n<>]+)/((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<i>$2</i>$3"); - - // _underline_ - // <span class="u">underline</span> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A))_([^\\_\\n<>]+)_((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<span class=\"u\">$2</span>$3"); - - // /12 - // <a href="#12">/12</a> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A))\\/(\\d+)((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<a href=\"#$2\">/$2</a>$3"); - - // @username@jabber.org - // <a href="http://juick.com/username@jabber.org/">@username@jabber.org</a> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A))@([\\w\\-\\.]+@[\\w\\-\\.]+)((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<a href=\"http://juick.com/$2/\">@$2</a>$3"); - - // @username - // <a href="http://juick.com/username/">@username</a> - msg = msg.replaceAll("((?<=\\s)|(?<=\\A))@([\\w\\-]{2,16})((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<a href=\"http://juick.com/$2/\">@$2</a>$3"); - - // (http://juick.com/last?page=2) - // (<a href="http://juick.com/last?page=2" rel="nofollow">juick.com</a>) - Matcher m = regexLinks2.matcher(msg); - StringBuffer sb = new StringBuffer(); - while (m.find()) { - String url = m.group(3).replace(" ", "%20").replaceAll("\\s+", ""); - m.appendReplacement(sb, "$1$2<a href=\"" + url + "\" rel=\"nofollow\">$4</a>$5"); - } - m.appendTail(sb); - msg = sb.toString(); - - // > citate - msg = msg.replaceAll("(?:(?<=\\n)|(?<=\\A))> *(.*)?(\\n|(?=\\Z))", "<q>$1</q>"); - msg = msg.replaceAll("</q><q>", "\n"); - - msg = msg.replaceAll("\n", "<br/>\n"); - return msg; - } public static void printMessages(PrintWriter out, JdbcTemplate sql, com.juick.User user, List<Integer> mids, com.juick.User visitor, int YandexID, int ad_mid) { List<com.juick.Message> msgs = MessagesQueries.getMessages(sql, mids); @@ -409,9 +317,9 @@ public class PageTemplates { String txt; if (!msg.Tags.isEmpty() && msg.Tags.contains("code")) { - txt = formatMessageCode(msg.getText()); + txt = Utils.formatMessageCode(msg.getText()); } else { - txt = formatMessage(msg.getText()); + txt = Utils.formatMessage(msg.getText()); } out.println("<article data-mid=\"" + msg.getMID() + "\">"); diff --git a/juick-www/src/main/java/com/juick/www/RSS.java b/juick-www/src/main/java/com/juick/www/RSS.java index 48510ce3..23120140 100644 --- a/juick-www/src/main/java/com/juick/www/RSS.java +++ b/juick-www/src/main/java/com/juick/www/RSS.java @@ -70,7 +70,7 @@ public class RSS { } } out.println("]]></title>"); - out.println("<description><![CDATA[" + PageTemplates.formatMessage(msg.getText()) + "]]></description>"); + out.println("<description><![CDATA[" + Utils.formatMessage(msg.getText()) + "]]></description>"); Date date = msg.getDate(); out.println("<pubDate>" + sdfRSS.format(date) + "</pubDate>"); diff --git a/juick-www/src/main/java/com/juick/www/UserThread.java b/juick-www/src/main/java/com/juick/www/UserThread.java index c201fca3..c3228e17 100644 --- a/juick-www/src/main/java/com/juick/www/UserThread.java +++ b/juick-www/src/main/java/com/juick/www/UserThread.java @@ -106,9 +106,9 @@ public class UserThread { String txt; if (!msg.Tags.isEmpty() && msg.Tags.contains("code")) { - txt = PageTemplates.formatMessageCode(msg.getText()); + txt = Utils.formatMessageCode(msg.getText()); } else { - txt = PageTemplates.formatMessage(msg.getText()); + txt = Utils.formatMessage(msg.getText()); } if (!tags.isEmpty()) { @@ -288,7 +288,7 @@ public class UserThread { out.println(" <div class=\"msg-avatar\"><img src=\"//i.juick.com/av-96.png\"/></div>"); out.println(" <div class=\"msg-header\">[удалено]:</div>"); } - out.println(" <div class=\"msg-txt\">" + PageTemplates.formatMessage(msg.getText()) + "</div>"); + out.println(" <div class=\"msg-txt\">" + Utils.formatMessage(msg.getText()) + "</div>"); if (msg.AttachmentType != null) { out.println(" <div class=\"msg-media\"><a href=\"//i.juick.com/p/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\"><img src=\"//i.juick.com/photos-512/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\" alt=\"\"/></a></div>"); } @@ -328,8 +328,7 @@ public class UserThread { out.println(" <div class=\"msg-avatar\"><img src=\"//i.juick.com/av-96.png\"/></div>"); out.println(" <div class=\"msg-header\">[удалено]:</div>"); } - - out.println(" <div class=\"msg-txt\">" + PageTemplates.formatMessage(msg.getText()) + "</div>"); + out.println(" <div class=\"msg-txt\">" + Utils.formatMessage(msg.getText()) + "</div>"); if (msg.AttachmentType != null) { out.println(" <div class=\"msg-media\"><a href=\"//i.juick.com/p/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\"><img src=\"//i.juick.com/photos-512/" + msg.getMID() + "-" + msg.getRID() + "." + msg.AttachmentType + "\" alt=\"\"/></a></div>"); } diff --git a/juick-www/src/main/java/com/juick/www/Utils.java b/juick-www/src/main/java/com/juick/www/Utils.java index 26e938a7..ee2fa212 100644 --- a/juick-www/src/main/java/com/juick/www/Utils.java +++ b/juick-www/src/main/java/com/juick/www/Utils.java @@ -18,6 +18,7 @@ package com.juick.www; import com.juick.User; +import com.mitchellbosecke.pebble.PebbleEngine; import org.springframework.jdbc.core.JdbcTemplate; import javax.servlet.http.Cookie; @@ -30,6 +31,8 @@ import java.net.URLConnection; import java.util.UUID; import java.util.logging.Level; import java.util.logging.Logger; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * @@ -38,6 +41,7 @@ import java.util.logging.Logger; public class Utils { private static final Logger logger = Logger.getLogger(Utils.class.getName()); + private static final PebbleEngine engine = new PebbleEngine.Builder().build(); public static String getCookie(HttpServletRequest request, String name) { Cookie cookies[] = request.getCookies(); @@ -199,4 +203,100 @@ public class Utils { return attachmentFName; } } + + private static Pattern regexLinks2 = Pattern.compile("((?<=\\s)|(?<=\\A))([\\[\\{]|<)((?:ht|f)tps?://(?:www\\.)?([^\\/\\s\\\"\\)\\!]+)/?(?:[^\\]\\}](?<!>))*)([\\]\\}]|>)"); + + public static String formatMessageCode(String msg) { + msg = msg.replaceAll("&", "&"); + msg = msg.replaceAll("<", "<"); + msg = msg.replaceAll(">", ">"); + + // http://juick.com/last?page=2 + // <a href="http://juick.com/last?page=2" rel="nofollow">http://juick.com/last?page=2</a> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A))((?:ht|f)tps?://(?:www\\.)?([^\\/\\s\\n\\\"]+)/?[^\\s\\n\\\"]*)", "$1<a href=\"$2\" rel=\"nofollow\">$2</a>"); + + // (http://juick.com/last?page=2) + // (<a href="http://juick.com/last?page=2" rel="nofollow">http://juick.com/last?page=2</a>) + Matcher m = regexLinks2.matcher(msg); + StringBuffer sb = new StringBuffer(); + while (m.find()) { + String url = m.group(3).replace(" ", "%20").replaceAll("\\s+", ""); + m.appendReplacement(sb, "$1$2<a href=\"" + url + "\" rel=\"nofollow\">" + url + "</a>$5"); + } + m.appendTail(sb); + msg = sb.toString(); + + return "<pre>" + msg + "</pre>"; + } + public static String formatMessage(String msg) { + msg = msg.replaceAll("&", "&"); + msg = msg.replaceAll("<", "<"); + msg = msg.replaceAll(">", ">"); + + // -- + // — + msg = msg.replaceAll("((?<=\\s)|(?<=\\A))\\-\\-?((?=\\s)|(?=\\Z))", "$1—$2"); + + // http://juick.com/last?page=2 + // <a href="http://juick.com/last?page=2" rel="nofollow">juick.com</a> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A))((?:ht|f)tps?://(?:www\\.)?([^\\/\\s\\n\\\"]+)/?[^\\s\\n\\\"]*)", "$1<a href=\"$2\" rel=\"nofollow\">$3</a>"); + + // [link text][http://juick.com/last?page=2] + // <a href="http://juick.com/last?page=2" rel="nofollow">link text</a> + msg = msg.replaceAll("\\[([^\\]]+)\\]\\[((?:ht|f)tps?://[^\\]]+)\\]", "<a href=\"$2\" rel=\"nofollow\">$1</a>"); + msg = msg.replaceAll("\\[([^\\]]+)\\]\\(((?:ht|f)tps?://[^\\)]+)\\)", "<a href=\"$2\" rel=\"nofollow\">$1</a>"); + + // #12345 + // <a href="http://juick.com/12345">#12345</a> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A)|(?<=\\p{Punct}))#(\\d+)((?=\\s)|(?=\\Z)|(?=\\))|(?=\\.)|(?=\\,))", "$1<a href=\"http://juick.com/$2\">#$2</a>$3"); + + // #12345/65 + // <a href="http://juick.com/12345#65">#12345/65</a> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A)|(?<=\\p{Punct}))#(\\d+)/(\\d+)((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<a href=\"http://juick.com/$2#$3\">#$2/$3</a>$4"); + + // *bold* + // <b>bold</b> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A)|(?<=\\p{Punct}))\\*([^\\*\\n<>]+)\\*((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<b>$2</b>$3"); + + // /italic/ + // <i>italic</i> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A))/([^\\/\\n<>]+)/((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<i>$2</i>$3"); + + // _underline_ + // <span class="u">underline</span> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A))_([^\\_\\n<>]+)_((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<span class=\"u\">$2</span>$3"); + + // /12 + // <a href="#12">/12</a> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A))\\/(\\d+)((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<a href=\"#$2\">/$2</a>$3"); + + // @username@jabber.org + // <a href="http://juick.com/username@jabber.org/">@username@jabber.org</a> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A))@([\\w\\-\\.]+@[\\w\\-\\.]+)((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<a href=\"http://juick.com/$2/\">@$2</a>$3"); + + // @username + // <a href="http://juick.com/username/">@username</a> + msg = msg.replaceAll("((?<=\\s)|(?<=\\A))@([\\w\\-]{2,16})((?=\\s)|(?=\\Z)|(?=\\p{Punct}))", "$1<a href=\"http://juick.com/$2/\">@$2</a>$3"); + + // (http://juick.com/last?page=2) + // (<a href="http://juick.com/last?page=2" rel="nofollow">juick.com</a>) + Matcher m = regexLinks2.matcher(msg); + StringBuffer sb = new StringBuffer(); + while (m.find()) { + String url = m.group(3).replace(" ", "%20").replaceAll("\\s+", ""); + m.appendReplacement(sb, "$1$2<a href=\"" + url + "\" rel=\"nofollow\">$4</a>$5"); + } + m.appendTail(sb); + msg = sb.toString(); + + // > citate + msg = msg.replaceAll("(?:(?<=\\n)|(?<=\\A))> *(.*)?(\\n|(?=\\Z))", "<q>$1</q>"); + msg = msg.replaceAll("</q><q>", "\n"); + + msg = msg.replaceAll("\n", "<br/>\n"); + return msg; + } + public static PebbleEngine getEngine() { + return engine; + } } diff --git a/juick-www/src/main/resources/layouts/content.html b/juick-www/src/main/resources/layouts/content.html new file mode 100644 index 00000000..4cc1e2bf --- /dev/null +++ b/juick-www/src/main/resources/layouts/content.html @@ -0,0 +1,29 @@ +<!DOCTYPE html> +<html> +<head> + <meta charset="utf-8"> + <meta http-equiv="X-UA-Compatible" content="IE=edge"> + <script type="text/javascript" src="/scripts.js"></script> + <link rel="stylesheet" type="text/css" href="/style.css"/> + {% block headers %} + {{ headers | raw }} + {% endblock %} + <title>{{ title }}</title> + <meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no"/> + <link rel="icon" href="//i.juick.com/favicon.png"/> + <!--[if lt IE 9 & (!IEMobile 7)]> + <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js"></script> + <![endif]--> +</head> +<body> +{% include "views/partial/navigation.html" %} + <section id="content"> + {% block content %} + {% endblock %} + </section> + <aside id="column"> + {% block column %} + {% endblock %} + </aside> +</body> +</html>
\ No newline at end of file diff --git a/juick-www/src/main/resources/views/partial/homecolumn.html b/juick-www/src/main/resources/views/partial/homecolumn.html new file mode 100644 index 00000000..5293918d --- /dev/null +++ b/juick-www/src/main/resources/views/partial/homecolumn.html @@ -0,0 +1,6 @@ +<p class="tags"> + {% include "views/partial/tags.html" %} + {% if showAdv %} + <a href="http://ru.wix.com/">конструктор сайтов</a> + {% endif %} +</p>
\ No newline at end of file diff --git a/juick-www/src/main/resources/views/partial/navigation.html b/juick-www/src/main/resources/views/partial/navigation.html new file mode 100644 index 00000000..7cacf66f --- /dev/null +++ b/juick-www/src/main/resources/views/partial/navigation.html @@ -0,0 +1,37 @@ +<header> + <div id="logo"><a href="/">Juick</a></div> + <nav id="global"> + <ul> + <li><a href="/">Популярные</a></li> + <li><a href="/?show=all" rel="nofollow">Все сообщения</a></li> + <li><a href="/?show=photos" rel="nofollow">Фотографии</a></li> + </ul> + </nav> + <div id="search"> + <form action="/"> + <input type="text" name="search" class="text" placeholder="Поиск" value="{{ search }}"/> + </form> + </div> + <section id="headdiv"> + {% if visitor.getUID() > 0 %} + <nav id="user"> + <ul> + <li><a href="/?show=my">Моя лента</a></li> + <li><a href="/pm/inbox">Приватные</a></li> + <li><a href="/?show=discuss">Обсуждения</a></li> + <li><a href="/?show=recommended">Рекомендации</a></li> + </ul> + </nav> + <nav id="actions"> + <ul> + <li><a href="/#post">Написать</a></li> + <li><a href="/{{ visitor.getUName() }}">@{{ visitor.getUName() }}</a></li> + <li><a href="/logout">Выйти</a></li> + </ul> + </nav> + {% else %} + <p>Чтобы добавлять сообщения и комментарии, <a href="#" onclick="return Juick.openDialogLogin()">представьтесь</a>. + </p> + {% endif %} + </section> +</header>
\ No newline at end of file diff --git a/juick-www/src/main/resources/views/partial/tags.html b/juick-www/src/main/resources/views/partial/tags.html new file mode 100644 index 00000000..e69a949d --- /dev/null +++ b/juick-www/src/main/resources/views/partial/tags.html @@ -0,0 +1,7 @@ +{% for tag in tags %} +<span> + <!-- TODO: tagscloud: font-size: small, large, x-large, xx-large !--> + <a onclick="return addTag('{{ tag.Name }}')" href="/{{ user.getUName() }}/?tag={{tag.Name}}" + title="{{ tag.Name }}" class="usage_{{ tag.UsageCnt }}">{{ tag.Name }}</a> +</span> +{% endfor %}
\ No newline at end of file diff --git a/juick-www/src/main/resources/views/pm_inbox.html b/juick-www/src/main/resources/views/pm_inbox.html new file mode 100644 index 00000000..d53c81ba --- /dev/null +++ b/juick-www/src/main/resources/views/pm_inbox.html @@ -0,0 +1,36 @@ +{% extends "layouts/content.html" %} +{% block content %} +{% if not msgs.isEmpty() %} +<ul id="private-messages"> + {% for msg in msgs %} + <li class="msg"> + <div class="msg-cont"> + <div class="msg-ts">{{ msg.getDate() }}</div> + <div class="msg-avatar"> + <a href="/{{ msg.getUser().getUName() }}/"> + <img src="//i.juick.com/a/{{ msg.getUser().getUID() }}.png" alt="{{ msg.getUser().getUName() }}"/> + </a> + </div> + <div class="msg-header"> + <a href="/{{ msg.getUser().getUName() }}/">@{{ msg.getUser().getUName() }}</a>: + </div> + <div class="msg-txt">{{ msg.getText() | raw }}</div> + + <form action="/pm/send" method="POST" enctype="multipart/form-data"> + <input type="hidden" name="uname" value="{{ msg.getUser().getUName() }}"/> + <div class="msg-comment"> + <div class="ta-wrapper"> + <textarea name="body" rows="1" class="replypm" placeholder="Написать ответ"></textarea> + </div> + </div> + </form> + + </div> + </li> + {% endfor %} +</ul> +{% endif %} +{% endblock %} +{% block "column" %} +{% include "views/partial/homecolumn.html" %} +{% endblock %}
\ No newline at end of file |