diff options
author | 2016-12-28 22:38:21 +0300 | |
---|---|---|
committer | 2017-01-10 12:08:35 +0300 | |
commit | 2f682b5e3cfc3fc5f961b60129be7bc90e0d6a03 (patch) | |
tree | 840aea9eb94d5c1f667a710d3298135854bc5002 /juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java | |
parent | eb440ea4f120115613880e340b010eed5397e72c (diff) |
juick-www: now on spring-webmvc
Diffstat (limited to 'juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java')
-rw-r--r-- | juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java b/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java new file mode 100644 index 00000000..3152d5fc --- /dev/null +++ b/juick-www/src/main/java/com/juick/www/controllers/PageTemplates.java @@ -0,0 +1,381 @@ +/* + * Juick + * Copyright (C) 2008-2011, Ugnich Anton + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +package com.juick.www.controllers; + +import com.juick.Message; +import com.juick.server.helpers.TagStats; +import com.juick.service.MessagesService; +import com.juick.service.TagService; +import com.juick.service.UserService; +import com.juick.util.MessageUtils; +import org.apache.commons.lang3.CharEncoding; +import org.apache.commons.lang3.StringEscapeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.StringUtils; +import ru.sape.Sape; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Calendar; +import java.util.Date; +import java.util.List; +import java.util.stream.Collectors; + +/** + * @author Ugnich Anton + */ +public class PageTemplates { + + private static final Logger logger = LoggerFactory.getLogger(PageTemplates.class); + + public Sape sape = null; + protected static final SimpleDateFormat sdfSQL = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + private static SimpleDateFormat sdfSimple = new SimpleDateFormat("d MMM"); + private static SimpleDateFormat sdfFull = new SimpleDateFormat("d MMM yyyy"); + private static String tagsHTML = null; + + @Inject + TagService tagService; + @Inject + MessagesService messagesService; + @Inject + UserService userService; + + public void pageHead(PrintWriter out, com.juick.User visitor, 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?v=2\"/>"); + 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.flush(); + if (visitor.getUid() > 0) { + out.println("<body id=\"body\" data-hash=\"" + visitor.getAuthHash() + "\">"); + } else { + out.println("<body id=\"body\">"); + } + } + + public 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=\"" + StringEscapeUtils.escapeHtml4(search) + "\""); + } + out.println("/></form></div>"); + out.println(" <section id=\"headdiv\">"); + if (visitor.getUid() > 0) { + 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.getName() + "\">@" + visitor.getName() + "</a></li>"); + out.print("<li><a href=\"/logout\">Выйти</a></li>"); + out.println("</ul></nav>"); + } else { + out.println("<p>Чтобы добавлять сообщения и комментарии, <a href=\"#\" class=\"a-login\">представьтесь</a>.</p>"); + } + out.println(" </section>"); + out.println("</header>"); + } + + public void pageHomeColumn(PrintWriter out, com.juick.User visitor) { + pageHomeColumn(out, visitor, false); + } + + public void pageHomeColumn(PrintWriter out, com.juick.User visitor, boolean showAdv) { + if (tagsHTML == null) { + tagsHTML = formatPopularTags(80); + } + + out.println("<aside id=\"column\">"); + out.print(" <p class=\"tags\">" + tagsHTML); + if (showAdv) { + out.print(" <a href=\"http://ru.wix.com/\">конструктор сайтов</a>"); + } + out.println("</p>"); +// if (visitor != null) { +// printContestRating(out, sql); +// } + out.println("</aside>"); + } + + public String formatPopularTags(int cnt) { + List<String> popularTags = tagService.getPopularTags().stream() + .map(t -> "<a href=\"/tag/" + URLEncoder.encode(t) + "\">" + StringEscapeUtils.escapeHtml4(t) + "</a>").collect(Collectors.toList()); + return StringUtils.collectionToDelimitedString(popularTags, " "); + } + + public void pageFooter(HttpServletRequest request, PrintWriter out, com.juick.User visitor, boolean sapeon) { + out.println("<div id=\"footer\">"); + out.println(" <div id=\"footer-right\"><a href=\"/settings\" rel=\"nofollow\">Настройки</a> · <a href=\"/help/ru/contacts\" rel=\"nofollow\">Контакты</a> · <a href=\"/help/\" rel=\"nofollow\">Справка</a> · <a href=\"/help/ru/adv\" rel=\"nofollow\">Реклама</a></div>"); + out.print(" <div id=\"footer-social\">"); + out.print("<a href=\"https://twitter.com/Juick\" rel=\"nofollow\" class=\"ico32-twi\">Twitter</a>"); + out.print("<a href=\"https://vk.com/juick\" rel=\"nofollow\" class=\"ico32-vk\">ВКонтакте</a>"); + out.print("<a href=\"https://www.facebook.com/JuickCom\" rel=\"nofollow\" class=\"ico32-fb\">Facebook</a>"); + out.println("</div>"); + out.print(" <div id=\"footer-left\">juick.com © 2008-2016"); + + String queryString = request.getQueryString(); + String requestURI = request.getRequestURI(); + if (sapeon && sape != null && (visitor.getUid() == 0 || visitor.getUid() == 1) && queryString == null) { + String links = sape.getPageLinks(requestURI, request.getCookies()).render(); + if (links != null && !links.isEmpty()) { + out.print("<br/>Спонсоры: " + links); + } + } + + out.println("</div>"); + out.println("</div>"); + + out.println("<script>"); + out.println("(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){"); + out.println("(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),"); + out.println("m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)"); + out.println("})(window,document,'script','//www.google-analytics.com/analytics.js','ga');"); + out.println("ga('create','UA-385578-4','juick.com');"); + out.println("ga('require','displayfeatures');"); + out.println("ga('send','pageview');"); + + if (sapeon) { + out.println("var _acic={dataProvider:10};"); + out.println("(function(){"); + out.println("var e=document.createElement('script');e.type='text/javascript';e.async=true;e.src='//www2.aci'+'nt.net/aci.js';"); + out.println("var t=document.getElementsByTagName('script')[0];t.parentNode.insertBefore(e,t);"); + out.println("})();"); + } + + out.println("</script>"); + } + + public void pageEnd(PrintWriter out) { + out.println("</body></html>"); + } + + public String formatTags(List<TagStats> tags) { + String ret = org.apache.commons.lang3.StringUtils.EMPTY; + for (TagStats tag : tags) { + String tagName = StringEscapeUtils.escapeHtml4(tag.getTag().getName()); + try { + ret += "<a href=\"/tag/" + URLEncoder.encode(tag.getTag().getName(), CharEncoding.UTF_8) + "\""; + if (tag.getUsageCount() < 2) { + ret += " rel=\"nofollow\""; + } + ret += ">" + tagName + "</a>"; + } catch (UnsupportedEncodingException e) { + } + } + + return ret; + } + + public String formatDate(int minutes, Date fulldate) { + if (minutes < 1) { + return "сейчас"; + } else if (minutes < 60) { + String unit; + int ld = minutes % 10; + if ((minutes < 10 || minutes > 20) && ld == 1) { + unit = "минуту"; + } else if ((minutes < 10 || minutes > 20) && ld > 1 && ld < 5) { + unit = "минуты"; + } else { + unit = "минут"; + } + return minutes + " " + unit + " назад"; + } else if (minutes < 1440) { + int hours = (minutes / 60); + String unit; + int ld = hours % 10; + if ((hours < 10 || hours > 20) && ld == 1) { + unit = "час"; + } else if ((hours < 10 || hours > 20) && ld > 1 && ld < 5) { + unit = "часа"; + } else { + unit = "часов"; + } + return hours + " " + unit + " назад"; + } else if (minutes < 20160) { + int days = (minutes / 1440); + String unit; + int ld = days % 10; + if ((days < 10 || days > 20) && ld == 1) { + unit = "день"; + } else if ((days < 10 || days > 20) && ld > 1 && ld < 5) { + unit = "дня"; + } else { + unit = "дней"; + } + return days + " " + unit + " назад"; + } else { + String ret = sdfFull.format(fulldate); + synchronized (sdfSQL) { + try { + Calendar c = Calendar.getInstance(); + int curyear = c.get(Calendar.YEAR); + c.setTime(fulldate); + if (c.get(Calendar.YEAR) == curyear) { + ret = sdfSimple.format(fulldate); + } else { + ret = sdfFull.format(fulldate); + } + } catch (Exception e) { + logger.error("PARSE EXCEPTION: {}, exception {}", fulldate, e); + } + } + return ret; + } + } + + public String formatJSLocalTime(Date ts) { + return "<script type=\"text/javascript\">" + + "var d=new Date(" + ts.getTime() + ");" + + "document.write((d.getDate()<10?'0':'')+d.getDate()+'.'+(d.getMonth()<9?'0':'')+(d.getMonth()+1)+'.'+d.getFullYear()+' '+(d.getHours()<10?'0':'')+d.getHours()+':'+(d.getMinutes()<10?'0':'')+d.getMinutes());" + + "</script>"; + } + + public String formatReplies(int replies) { + int ld = replies % 10; + int lh = replies % 100; + if ((lh < 10 || lh > 20) && ld == 1) { + return replies + " ответ"; + } else if ((lh < 10 || lh > 20) && ld > 1 && ld < 5) { + return replies + " ответа"; + } else { + return replies + " ответов"; + } + } + + public void printMessages(PrintWriter out, com.juick.User user, List<Integer> mids, com.juick.User visitor, int YandexID, int ad_mid) { + List<com.juick.Message> msgs = messagesService.getMessages(mids); + + for (int i = 0; i < msgs.size(); i++) { + com.juick.Message msg = msgs.get(i); + if (msg.getMid() == ad_mid) { + msgs.remove(i); + msgs.add(0, msg); + break; + } + } + + List<Integer> blUIDs = new ArrayList<Integer>(20); + if (visitor != null) { + for (Message msg : msgs) { + blUIDs.add(msg.getUser().getUid()); + } + blUIDs = userService.checkBL(visitor.getUid(), blUIDs); + } + + for (Message msg : msgs) { + + List<TagStats> tags = tagService.getMessageTags(msg.getMid()); + String tagsStr = formatTags(tags); + if (msg.ReadOnly) { + tagsStr += "<a>readonly</a>"; + } + if (msg.getPrivacy() < 0) { + tagsStr += "<a>friends</a>"; + } + if (msg.getMid() == ad_mid) { + tagsStr += "<a>реклама</a>"; + } + + String txt; + if (msg.getTags().stream().anyMatch(t -> t.getName().equals("code"))) { + txt = MessageUtils.formatMessageCode(msg.getText()); + } else { + txt = MessageUtils.formatMessage(msg.getText()); + } + + out.println("<article data-mid=\"" + msg.getMid() + "\">"); + out.println(" <header class=\"u\">"); + out.println(" @<a href=\"/" + msg.getUser().getName() + "/\">" + msg.getUser().getName() + "</a>:"); + out.println(" <div class=\"msg-avatar\"><a href=\"/" + msg.getUser().getName() + "/\"><img src=\"//i.juick.com/a/" + msg.getUser().getUid() + ".png\" alt=\"" + msg.getUser().getName() + "\"/></a></div>"); + out.println(" <div class=\"msg-ts\"><a href=\"/" + msg.getUser().getName() + "/" + msg.getMid() + "\"><time datetime=\"" + sdfSQL.format(msg.getDate()) + "Z\" title=\"" + sdfSQL.format(msg.getDate()) + " GMT\">" + formatDate(msg.TimeAgo, msg.getDate()) + "</time></a></div>"); + + out.println(" <div class=\"msg-tags\">" + tagsStr + "</div>"); + out.println(" </header>"); + + if (msg.getAttachmentType() != null) { + String fname = msg.getMid() + "." + msg.getAttachmentType(); + out.println(" <p class=\"ir\"><a href=\"//i.juick.com/photos-512/" + fname + "\" data-fname=\"" + fname + "\"><img src=\"//i.juick.com/photos-512/" + fname + "\" alt=\"\"/></a></p>"); + } + out.println(" <p>" + txt + "</p>"); + if (msg.getAttachmentType() != null) { + out.println(" <div class=\"irbr\"></div>"); + } + out.print(" <nav class=\"l\">"); + msg.ReadOnly |= blUIDs.contains(msg.getUser().getUid()); + if (visitor.getUid() == 0) { + out.print("<a href=\"#\" class=\"a-login\">Рекомендовать</a>"); + } else { + out.print("<a href=\"/post?body=!+%23" + msg.getMid() + "\" class=\"a-like\">Рекомендовать</a>"); + } + if (visitor.getUid() == 0 && !msg.ReadOnly) { + out.print("<a href=\"/" + msg.getMid() + "\" class=\"a-login\">Комментировать</a> "); + } else if (visitor.getUid() > 0 && (!msg.ReadOnly || visitor.getUid() == msg.getUser().getUid())) { + out.print("<a class=\"a-comment\" href=\"/" + msg.getMid() + "\">Комментировать</a> "); + } + if (visitor.getUid() > 0 && msg.getPrivacy() < 0 && msg.getUser().getUid() == visitor.getUid()) { + out.print(" <a href=\"#\" class=\"a-privacy\">Открыть доступ</a>"); + } + if (visitor.getUid() > 0 && visitor.getUid() == 3694) { + out.print(" <a href=\"#\" class=\"a-popular-plus\">+</a>"); + out.print(" <a href=\"#\" class=\"a-popular-minus\">-</a>"); + out.print(" <a href=\"#\" class=\"a-popular-delete\">x</a>"); + } + out.println("</nav>"); + + out.print(" <nav class=\"s\">"); + if (msg.getLikes() > 0) { + out.print("<a href=\"/" + msg.getUser().getName() + "/" + msg.getMid() + "\" class=\"likes\"><i data-icon=\"ei-heart\" data-size=\"s\"></i> " + msg.getLikes() + "</a>"); + } + if (msg.getReplies() > 0) { + out.print("<a href=\"/" + msg.getUser().getName() + "/" + msg.getMid() + "\" class=\"replies\"><i data-icon=\"ei-comment\" data-size=\"s\"></i> " + msg.getReplies() + "</a>"); + } + out.println("</nav>"); + out.print("</article>"); + } + } +} |