diff options
Diffstat (limited to 'src/main/java/com/juick')
-rw-r--r-- | src/main/java/com/juick/JuickApplication.java | 56 | ||||
-rw-r--r-- | src/main/java/com/juick/http/www/Home.java | 13 | ||||
-rw-r--r-- | src/main/java/com/juick/http/www/Main.java | 4 | ||||
-rw-r--r-- | src/main/java/com/juick/http/www/NewMessage.java | 33 | ||||
-rw-r--r-- | src/main/java/com/juick/http/www/PageTemplates.java | 80 | ||||
-rw-r--r-- | src/main/java/com/juick/http/www/User.java | 73 | ||||
-rw-r--r-- | src/main/java/com/juick/http/www/Utils.java | 1 |
7 files changed, 147 insertions, 113 deletions
diff --git a/src/main/java/com/juick/JuickApplication.java b/src/main/java/com/juick/JuickApplication.java index ce242222..e546f5a8 100644 --- a/src/main/java/com/juick/JuickApplication.java +++ b/src/main/java/com/juick/JuickApplication.java @@ -4,6 +4,7 @@ import com.juick.xmpp.JID; import com.juick.xmpp.Stream; import com.juick.xmpp.StreamComponent; import com.juick.xmpp.s2s.S2SComponent; +import org.rythmengine.Rythm; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.datasource.DriverManagerDataSource; @@ -12,9 +13,7 @@ import java.net.InetSocketAddress; import java.nio.channels.AsynchronousSocketChannel; import java.nio.channels.Channels; import java.nio.channels.CompletionHandler; -import java.util.ArrayList; -import java.util.List; -import java.util.Properties; +import java.util.*; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.logging.Level; @@ -32,17 +31,34 @@ public class JuickApplication { private JdbcTemplate sql; private JdbcTemplate sqlSearch; private List<JuickComponent> components = new ArrayList<>(); + private String applicationPath; - public JuickApplication(Properties conf) throws IOException { + public JuickApplication(Properties conf, String applicationPath) throws IOException { + this.applicationPath = applicationPath; executorService = Executors.newWorkStealingPool(); - DriverManagerDataSource dataSource = new DriverManagerDataSource(); - dataSource.setDriverClassName(conf.getProperty("datasource_driver", "com.mysql.jdbc.Driver")); - dataSource.setUrl(conf.getProperty("datasource_url")); - sql = new JdbcTemplate(dataSource); - DriverManagerDataSource searchDatasource = new DriverManagerDataSource(); - searchDatasource.setDriverClassName("com.mysql.jdbc.Driver"); - searchDatasource.setUrl("jdbc:mysql://127.0.0.1:9306?autoReconnect=true&useUnicode=yes&characterEncoding=utf8&maxAllowedPacket=512000"); - sqlSearch = new JdbcTemplate(searchDatasource); + initDataSources(conf); + initSockets(conf); + initComponents(conf); + initRythm(conf); + } + + private void initRythm(Properties conf) { + String rythmMode = conf.getProperty("rythm_mode", "prod"); + Map<String, Object> map = new HashMap<>(); + map.put("home.template", applicationPath+"/WEB-INF/classes/templates"); + map.put("rythm.engine.mode", rythmMode); + Rythm.init(map); + } + + private void initComponents(Properties conf) { + if (!isHttpDevMode()) { + addComponent(new S2SComponent(this, conf)); + addComponent(new CrosspostComponent(sql, conf)); + addComponent(new PushComponent(sql, conf)); + } + } + + private void initSockets(final Properties conf) throws IOException { AsynchronousSocketChannel socket = AsynchronousSocketChannel.open(); socket.connect(new InetSocketAddress("localhost", 5347), socket, new CompletionHandler<Void, AsynchronousSocketChannel>() { @@ -60,11 +76,17 @@ public class JuickApplication { } } }); - if (!isHttpDevMode()) { - addComponent(new S2SComponent(this, conf)); - addComponent(new CrosspostComponent(sql, conf)); - addComponent(new PushComponent(sql, conf)); - } + } + + private void initDataSources(Properties conf) { + DriverManagerDataSource dataSource = new DriverManagerDataSource(); + dataSource.setDriverClassName(conf.getProperty("datasource_driver", "com.mysql.jdbc.Driver")); + dataSource.setUrl(conf.getProperty("datasource_url")); + sql = new JdbcTemplate(dataSource); + DriverManagerDataSource searchDatasource = new DriverManagerDataSource(); + searchDatasource.setDriverClassName("com.mysql.jdbc.Driver"); + searchDatasource.setUrl("jdbc:mysql://127.0.0.1:9306?autoReconnect=true&useUnicode=yes&characterEncoding=utf8&maxAllowedPacket=512000"); + sqlSearch = new JdbcTemplate(searchDatasource); } public static boolean isHttpDevMode() { diff --git a/src/main/java/com/juick/http/www/Home.java b/src/main/java/com/juick/http/www/Home.java index 3688b58e..b8047190 100644 --- a/src/main/java/com/juick/http/www/Home.java +++ b/src/main/java/com/juick/http/www/Home.java @@ -19,6 +19,7 @@ package com.juick.http.www; import com.juick.server.AdsQueries; import com.juick.server.MessagesQueries; +import org.rythmengine.Rythm; import org.springframework.jdbc.core.JdbcTemplate; import java.io.IOException; @@ -119,17 +120,9 @@ public class Home { out.println("<!--noindex-->"); } + if (visitor != null) { - out.println("<form action=\"/post\" method=\"post\" enctype=\"multipart/form-data\" onsubmit=\"return onsubmitNewMessage()\">"); - out.println("<section id=\"newmessage\">"); - out.println(" <textarea name=\"body\" placeholder=\"Новое сообщение...\" onclick=\"$('#newmessage>div').css('display','block');$('#newmessage textarea').css('min-height','70px');\" onkeypress=\"postformListener(this.form,event)\"></textarea>"); - out.println(" <div>"); - out.println(" <input type=\"text\" class=\"img\" name=\"img\" placeholder=\"Ссылка на изображение (JPG/PNG, до 10Мб)\"/> или <a href=\"#\" onclick=\"return attachMessagePhoto(this)\">загрузить</a><br/>"); - out.println(" <input type=\"text\" class=\"tags\" name=\"tags\" placeholder=\"Теги (через пробел)\"/><br/>"); - out.println(" <input type=\"submit\" class=\"subm\" value=\"Отправить\"/>"); - out.println(" </div>"); - out.println("</section>"); - out.println("</form>"); + out.println(Rythm.render("parts/post_form.html")); } if (mids.size() > 0) { diff --git a/src/main/java/com/juick/http/www/Main.java b/src/main/java/com/juick/http/www/Main.java index f37ae030..babeee1f 100644 --- a/src/main/java/com/juick/http/www/Main.java +++ b/src/main/java/com/juick/http/www/Main.java @@ -77,7 +77,7 @@ public class Main extends HttpServlet implements Stream.StreamListener { conf.getProperty("twitter_consumer_secret")); PageTemplates.sape = new Sape(conf.getProperty("sape_user"), "juick.com", 2000, 3600); Endpoints.wwwJuickCom = conf.getProperty("www_juick_com", "juick.com"); - app = new JuickApplication(conf); + app = new JuickApplication(conf, getServletContext().getRealPath("/")); sql = app.getSql(); sqlSearch = app.getSqlSearch(); pagesNewMessage = new NewMessage(app); @@ -171,6 +171,8 @@ public class Main extends HttpServlet implements Stream.StreamListener { help.doRedirectToHelpIndex(sql, request, response); } else if (uri.startsWith("/help/")) { help.doGetHelp(sql, request, response); + } else if (uri.startsWith("/my_tags.json")) { + pagesUser.doMyTagsJson(sql, request, response); } else if (uri.startsWith("/tag/")) { discover.doGet(sql, sqlSearch, request, response); } else if (uri.matches("^/\\d+$")) { diff --git a/src/main/java/com/juick/http/www/NewMessage.java b/src/main/java/com/juick/http/www/NewMessage.java index d3178c59..c8eb6ede 100644 --- a/src/main/java/com/juick/http/www/NewMessage.java +++ b/src/main/java/com/juick/http/www/NewMessage.java @@ -17,13 +17,10 @@ */ package com.juick.http.www; +import com.alibaba.fastjson.JSONArray; import com.juick.JuickApplication; import com.juick.Tag; -import com.juick.server.CrosspostQueries; -import com.juick.server.MessagesQueries; -import com.juick.server.SubscriptionsQueries; -import com.juick.server.TagQueries; -import com.juick.server.UserQueries; +import com.juick.server.*; import com.juick.xmpp.JID; import com.juick.xmpp.Message; import com.juick.xmpp.Stream; @@ -161,13 +158,25 @@ public class NewMessage { List<com.juick.Tag> tags = new ArrayList<>(); String tagsArr[] = new String[1]; if (tagsStr != null && !tagsStr.isEmpty()) { - tagsArr = tagsStr.split("[ \\,]"); - for (int i = 0; i < tagsArr.length; i++) { - if (tagsArr[i].startsWith("*")) { - tagsArr[i] = tagsArr[i].substring(1); + if (tagsStr.startsWith("[")) { + // new json tags format with auto-completion + JSONArray parse = (JSONArray)JSONArray.parse(tagsStr); + ArrayList<String> tagsList = new ArrayList<>(); + for(int i=0; i<parse.size(); i++) { + if (parse.get(i) instanceof String) { + tagsList.add(parse.getString(i)); + } } - if (tagsArr[i].length() > 64) { - tagsArr[i] = tagsArr[i].substring(0, 64); + tagsArr = tagsList.toArray(new String[tagsList.size()]); + } else { + tagsArr = tagsStr.split("[ \\,]"); + for (int i = 0; i < tagsArr.length; i++) { + if (tagsArr[i].startsWith("*")) { + tagsArr[i] = tagsArr[i].substring(1); + } + if (tagsArr[i].length() > 64) { + tagsArr[i] = tagsArr[i].substring(0, 64); + } } } tags = TagQueries.getTags(sql, tagsArr, true); @@ -289,7 +298,7 @@ public class NewMessage { out.println("<p><a href=\"https://www.facebook.com/sharer/sharer.php?u=" + url + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-fb sharenew\">Отправить в Facebook</a></p>"); } out.println("<p><a href=\"https://plus.google.com/share?url=" + url + "\" onclick=\"return openSocialWindow(this)\" class=\"ico32-gp sharenew\">Отправить в Google+</a></p>"); - out.println("<p>Ссылка на сообщение: <a href=\"http://juick.com/" + mid + "\">http://juick.com/" + mid + "</a></p>"); + out.println("<p>Ссылка на сообщение: <a href=\"http://"+ Endpoints.wwwJuickCom+"/" + mid + "\">http://"+Endpoints.wwwJuickCom+"/" + mid + "</a></p>"); out.println("</section>"); PageTemplates.pageFooter(request, out, visitor, false); diff --git a/src/main/java/com/juick/http/www/PageTemplates.java b/src/main/java/com/juick/http/www/PageTemplates.java index 3eb66877..2ae945a5 100644 --- a/src/main/java/com/juick/http/www/PageTemplates.java +++ b/src/main/java/com/juick/http/www/PageTemplates.java @@ -22,6 +22,7 @@ import com.juick.Tag; import com.juick.server.Endpoints; import com.juick.server.MessagesQueries; import com.juick.server.UserQueries; +import org.rythmengine.Rythm; import org.springframework.jdbc.core.JdbcTemplate; import ru.sape.Sape; @@ -51,58 +52,43 @@ public class PageTemplates { private static String tagsHTML = null; public static void pageHead(PrintWriter out, String title, String headers) { - out.println("<!DOCTYPE html>"); - out.print("<html>"); - out.print("<head>"); - out.println("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">"); - out.print("<link rel=\"stylesheet\" href=\"/style.css\"/>"); - out.print("<script type=\"text/javascript\" src=\"//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js\"></script>"); - out.print("<script type=\"text/javascript\" src=\"/scripts.js\"></script>"); - if (headers != null) { - out.print(headers); - } - out.print("<title>" + title + "</title>"); - out.println("<meta name=\"viewport\" content=\"width=device-width,initial-scale=1,user-scalable=no\"/>"); - out.println("<link rel=\"icon\" href=\"//i.juick.com/favicon.png\"/>"); - out.println("<!--[if lt IE 9 & (!IEMobile 7)]>"); - out.println("<script src=\"//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.min.js\"></script>"); - out.println("<![endif]-->"); - out.println("</head>"); + out.print(Rythm.render("parts/page_header.html", headers, title)); out.flush(); out.println("<body>"); } public static void pageNavigation(PrintWriter out, com.juick.User visitor, String search) { - out.println("<header>"); - out.println(" <div id=\"logo\"><a href=\"/\">Juick</a></div>"); - out.print(" <nav id=\"global\"><ul>"); - out.print("<li><a href=\"/\">Популярные</a></li>"); - out.print("<li><a href=\"/?show=all\" rel=\"nofollow\">Все сообщения</a></li>"); - out.print("<li><a href=\"/?show=photos\" rel=\"nofollow\">Фотографии</a></li>"); - out.println("</ul></nav>"); - out.print(" <div id=\"search\"><form action=\"/\"><input type=\"text\" name=\"search\" class=\"text\" placeholder=\"Поиск\""); - if (search != null) { - out.print(" value=\"" + Utils.encodeHTML(search) + "\""); - } - out.println("/></form></div>"); - out.println(" <section id=\"headdiv\">"); - if (visitor != null) { - out.print(" <nav id=\"user\"><ul>"); - out.print("<li><a href=\"/?show=my\">Моя лента</a></li>"); - out.print("<li><a href=\"/pm/inbox\">Приватные</a></li>"); - out.print("<li><a href=\"/?show=discuss\">Обсуждения</a></li>"); - out.print("<li><a href=\"/?show=recommended\">Рекомендации</a></li>"); - out.println("</ul></nav>"); - out.print(" <nav id=\"actions\"><ul>"); - out.print("<li><a href=\"/#post\">Написать</a></li>"); - out.print("<li><a href=\"/" + visitor.getUName() + "\">@" + visitor.getUName() + "</a></li>"); - out.print("<li><a href=\"/logout\">Выйти</a></li>"); - out.println("</ul></nav>"); - } else { - out.println("<p>Чтобы добавлять сообщения и комментарии, <a href=\"#\" onclick=\"return openDialogLogin()\">представьтесь</a>.</p>"); - } - out.println(" </section>"); - out.println("</header>"); + out.print(Rythm.render("parts/page_navigation.html", search, visitor)); +// out.println("<header>"); +// out.println(" <div id=\"logo\"><a href=\"/\">Juick</a></div>"); +// out.print(" <nav id=\"global\"><ul>"); +// out.print("<li><a href=\"/\">Популярные</a></li>"); +// out.print("<li><a href=\"/?show=all\" rel=\"nofollow\">Все сообщения</a></li>"); +// out.print("<li><a href=\"/?show=photos\" rel=\"nofollow\">Фотографии</a></li>"); +// out.println("</ul></nav>"); +// out.print(" <div id=\"search\"><form action=\"/\"><input type=\"text\" name=\"search\" class=\"text\" placeholder=\"Поиск\""); +// if (search != null) { +// out.print(" value=\"" + Utils.encodeHTML(search) + "\""); +// } +// out.println("/></form></div>"); +// out.println(" <section id=\"headdiv\">"); +// if (visitor != null) { +// out.print(" <nav id=\"user\"><ul>"); +// out.print("<li><a href=\"/?show=my\">Моя лента</a></li>"); +// out.print("<li><a href=\"/pm/inbox\">Приватные</a></li>"); +// out.print("<li><a href=\"/?show=discuss\">Обсуждения</a></li>"); +// out.print("<li><a href=\"/?show=recommended\">Рекомендации</a></li>"); +// out.println("</ul></nav>"); +// out.print(" <nav id=\"actions\"><ul>"); +// out.print("<li><a href=\"/#post\">Написать</a></li>"); +// out.print("<li><a href=\"/" + visitor.getUName() + "\">@" + visitor.getUName() + "</a></li>"); +// out.print("<li><a href=\"/logout\">Выйти</a></li>"); +// out.println("</ul></nav>"); +// } else { +// out.println("<p>Чтобы добавлять сообщения и комментарии, <a href=\"#\" onclick=\"return openDialogLogin()\">представьтесь</a>.</p>"); +// } +// out.println(" </section>"); +// out.println("</header>"); } public static void pageYandexAd728(PrintWriter out, int YandexID) { diff --git a/src/main/java/com/juick/http/www/User.java b/src/main/java/com/juick/http/www/User.java index 1f2b7dc0..5d06045c 100644 --- a/src/main/java/com/juick/http/www/User.java +++ b/src/main/java/com/juick/http/www/User.java @@ -17,25 +17,21 @@ */ package com.juick.http.www; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.serializer.JSONSerializer; import com.juick.Tag; import com.juick.server.Endpoints; import com.juick.server.MessagesQueries; import com.juick.server.TagQueries; import com.juick.server.UserQueries; -import com.juick.xmpp.Stream; import org.apache.commons.lang3.tuple.Pair; +import org.json.JSONArray; +import org.json.JSONObject; import org.springframework.jdbc.core.JdbcTemplate; import java.io.IOException; import java.io.PrintWriter; -import java.io.UnsupportedEncodingException; import java.net.URLEncoder; -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.stream.Collectors; import javax.servlet.ServletException; @@ -183,7 +179,7 @@ public class User { pageUserColumn(out, sql, user, visitor); out.println("<section id=\"content\">"); - out.println("<p>" + pageUserTags(sql, user, visitor, 0) + "</p>"); + out.println("<p>" + pageUserTags(sql, user, 0) + "</p>"); out.println("</section>"); PageTemplates.pageFooter(request, out, visitor, false); @@ -306,12 +302,16 @@ public class User { out.println(" <li><a href=\"./\">Блог</a></li>"); out.println(" <li><a href=\"./?show=recomm\" rel=\"nofollow\">Рекомендации</a></li>"); out.println(" <li><a href=\"./?show=photos\" rel=\"nofollow\">Фотографии</a></li>"); + if (visitor != null && visitor.getUID() == user.getUID()) { + out.println(" <li><a href=\"/?show=mycomments\" rel=\"nofollow\">Мои комментарии</a></li>"); + out.println(" <li><a href=\"/?show=unanswered\" rel=\"nofollow\">Неотвеченные</a></li>"); + } out.println(" </ul>"); out.println(" <hr/>"); out.println(" <form action=\"./\">"); out.println(" <p><input type=\"text\" name=\"search\" class=\"inp\" placeholder=\"Поиск\"/></p>"); out.println(" </form>"); - out.println(" <p class=\"tags\">" + pageUserTags(sql, user, visitor, 20) + "<a href=\"./tags\" rel=\"nofollow\">...</a></p>"); + out.println(" <p class=\"tags\">" + pageUserTags(sql, user, 20) + "<a href=\"./tags\" rel=\"nofollow\">...</a></p>"); out.println(" <hr/>"); out.println(" <div id=\"ustats\"><ul>"); out.println(" <li><a href=\"./friends\">Я читаю: " + UserQueries.getStatsIRead(sql, user.getUID()) + "</a></li>"); @@ -337,7 +337,28 @@ public class User { out.println("</aside>"); } - public static String pageUserTags(JdbcTemplate sql, com.juick.User user, com.juick.User visitor, int cnt) { + public static String pageUserTags(JdbcTemplate sql, com.juick.User user, int cnt) { + List<Tag> tags = getUserTags(sql, user, cnt); + + int maxUsageCnt = tags.size() > 0 ? tags.stream().mapToInt(tag -> tag.UsageCnt).max().getAsInt() : 1; + + return tags.stream().map(tag -> "<a href=\"./?tag=" + URLEncoder.encode(tag.Name) + + "\" title=\"" + tag.UsageCnt + "\" rel=\"nofollow\">" + tag.Name + "</a>") + .collect(Collectors.joining(" ")); + + /* + todo: + if (tags[i].UsageCnt > maxUsageCnt / 3 * 2) { + ret += "<big>" + tag + "</big> "; + } else if (tags[i].UsageCnt > maxUsageCnt / 3) { + ret += "<small>" + tag + "</small> "; + } else { + ret += tag + " "; + } + }*/ + } + + public static List<Tag> getUserTags(JdbcTemplate sql, com.juick.User user, int cnt) { List<Tag> tags; if (cnt > 0) { tags = sql.query("SELECT tags.name AS name,COUNT(DISTINCT messages_tags.message_id) AS cnt " + @@ -361,22 +382,22 @@ public class User { return t; }), user.getUID()); } + return tags; + } - int maxUsageCnt = tags.size() > 0 ? tags.stream().mapToInt(tag -> tag.UsageCnt).max().getAsInt() : 1; - - return tags.stream().map(tag -> "<a href=\"./?tag=" + URLEncoder.encode(tag.Name) + - "\" title=\"" + tag.UsageCnt + "\" rel=\"nofollow\">" + tag.Name + "</a>") - .collect(Collectors.joining(" ")); - - /* - todo: - if (tags[i].UsageCnt > maxUsageCnt / 3 * 2) { - ret += "<big>" + tag + "</big> "; - } else if (tags[i].UsageCnt > maxUsageCnt / 3) { - ret += "<small>" + tag + "</small> "; - } else { - ret += tag + " "; + public void doMyTagsJson(JdbcTemplate sql, HttpServletRequest request, HttpServletResponse response) throws IOException { + com.juick.User visitor = Utils.getVisitorUser(sql, request, response); + if (visitor != null) { + List<Tag> userTags = getUserTags(sql, visitor, 200); + JSONArray arr = new JSONArray(); + for (Tag userTag : userTags) { + arr.put(userTag.Name); } - }*/ + response.setContentType("text/json"); + response.setCharacterEncoding("UTF-8"); + response.getOutputStream().write(arr.toString().getBytes("UTF-8")); + } else { + response.sendError(404); + } } } diff --git a/src/main/java/com/juick/http/www/Utils.java b/src/main/java/com/juick/http/www/Utils.java index ab721020..16428842 100644 --- a/src/main/java/com/juick/http/www/Utils.java +++ b/src/main/java/com/juick/http/www/Utils.java @@ -162,6 +162,7 @@ public class Utils { } public static String encodeHTML(String str) { + if (str == null) return null; return str.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll("'", "'").replaceAll("\"", """).replaceAll("\n", " "); } |