From 7a2f89266c8f6337e4e81a2fd8488e0f80f4f9bd Mon Sep 17 00:00:00 2001 From: Vitaly Takmazov Date: Fri, 3 Apr 2020 23:53:23 +0300 Subject: Reorganize layout and code cleanup --- src/main/java/com/juick/www/controllers/Help.java | 7 +- .../com/juick/www/controllers/MessagesWWW.java | 590 --------------------- src/main/java/com/juick/www/controllers/Site.java | 590 +++++++++++++++++++++ 3 files changed, 592 insertions(+), 595 deletions(-) delete mode 100644 src/main/java/com/juick/www/controllers/MessagesWWW.java create mode 100644 src/main/java/com/juick/www/controllers/Site.java (limited to 'src/main/java/com/juick/www/controllers') diff --git a/src/main/java/com/juick/www/controllers/Help.java b/src/main/java/com/juick/www/controllers/Help.java index d2796def..7fc84060 100644 --- a/src/main/java/com/juick/www/controllers/Help.java +++ b/src/main/java/com/juick/www/controllers/Help.java @@ -19,10 +19,9 @@ package com.juick.www.controllers; import com.juick.model.User; import com.juick.server.util.HttpNotFoundException; -import com.juick.www.HelpService; -import com.juick.www.WebApp; -import com.juick.service.MessagesService; +import com.juick.service.HelpService; import com.juick.service.security.annotation.Visitor; +import com.juick.www.WebApp; import org.commonmark.parser.Parser; import org.commonmark.renderer.html.HtmlRenderer; import org.springframework.stereotype.Controller; @@ -42,8 +41,6 @@ public class Help { @Inject private HelpService helpService; @Inject - private MessagesService messagesService; - @Inject private Parser cmParser; @Inject private HtmlRenderer helpRenderer; diff --git a/src/main/java/com/juick/www/controllers/MessagesWWW.java b/src/main/java/com/juick/www/controllers/MessagesWWW.java deleted file mode 100644 index 4b0bb17f..00000000 --- a/src/main/java/com/juick/www/controllers/MessagesWWW.java +++ /dev/null @@ -1,590 +0,0 @@ -/* - * Copyright (C) 2008-2019, Juick - * - * 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 . - */ -package com.juick.www.controllers; - -import com.juick.model.Message; -import com.juick.model.Tag; -import com.juick.model.User; -import com.juick.formatters.PlainTextFormatter; -import com.juick.server.Utils; -import com.juick.server.util.HttpForbiddenException; -import com.juick.server.util.HttpNotFoundException; -import com.juick.server.util.WebUtils; -import com.juick.www.WebApp; -import com.juick.service.*; -import com.juick.service.security.annotation.Visitor; -import com.juick.util.MessageUtils; -import org.apache.commons.lang3.StringUtils; -import org.apache.commons.lang3.tuple.Pair; -import org.apache.commons.text.StringEscapeUtils; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.ModelMap; -import org.springframework.web.bind.annotation.*; - -import javax.inject.Inject; -import javax.servlet.http.HttpServletRequest; -import java.net.URLEncoder; -import java.nio.charset.StandardCharsets; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Collectors; - -/** - * - * @author Ugnich Anton - */ -@Controller -public class MessagesWWW { - @Inject - private UserService userService; - @Inject - private TagService tagService; - @Inject - private MessagesService messagesService; - @Inject - private PMQueriesService pmQueriesService; - @Inject - private CrosspostService crosspostService; - @Inject - private WebApp webApp; - - private void fillUserModel(ModelMap model, User user, User visitor) { - user.setAvatar(webApp.getAvatarWebPath(user)); - model.addAttribute("user", user); - model.addAttribute("isSubscribed", userService.isSubscribed(visitor.getUid(), user.getUid())); - model.addAttribute("isInBL", userService.isInBL(visitor.getUid(), user.getUid())); - model.addAttribute("isInBLAny", userService.isInBLAny(user.getUid(), visitor.getUid())); - model.addAttribute("statsIRead", userService.getUserFriends(user.getUid()).size()); - model.addAttribute("statsMyReaders", userService.getStatsMyReaders(user.getUid())); - model.addAttribute("statsMyBL", userService.getUserBLUsers(user.getUid()).size()); - model.addAttribute("statsMessages", userService.getStatsMessages(user.getUid())); - model.addAttribute("statsReplies", userService.getStatsReplies(user.getUid())); - model.addAttribute("iread", userService.getUserReadLeastPopular(user.getUid(), 8)); - model.addAttribute("tagStats", tagService.getUserTagStats(user.getUid()) - .stream().sorted((e1, e2) -> Integer.compare(e2.getUsageCount(), e1.getUsageCount())).limit(20).map(t -> t.getTag().getName()).collect(Collectors.toList())); - } - - @GetMapping("/") - protected String doGet( - @Visitor User visitor, - @RequestParam(required = false) String tag, - @RequestParam(name = "show", required = false) String paramShow, - @RequestParam(name = "search", required = false) String paramSearch, - @RequestParam(name = "before", required = false, defaultValue = "0") Integer paramBefore, - @RequestParam(name = "to", required = false, defaultValue = "0") Long paramTo, - @RequestParam(name = "page", required = false, defaultValue = "0") Integer page, - ModelMap model) { - if (tag != null) { - return "redirect:/tag/" + URLEncoder.encode(tag, StandardCharsets.UTF_8); - } - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - - if (paramSearch != null && paramSearch.length() > 64) { - paramSearch = null; - } - - model.addAttribute("discover", false); - - String title; - List mids; - - if (paramSearch != null) { - title = "Поиск: " + StringEscapeUtils.escapeHtml4(paramSearch); - mids = messagesService.getSearch(visitor, Utils.encodeSphinx(paramSearch), page); - } else if (paramShow == null) { - title = "Обсуждения"; - mids = messagesService.getDiscussions(visitor.getUid(), paramTo); - } else if (paramShow.equals("top")) { - title = "Популярные"; - mids = messagesService.getPopular(visitor.getUid(), paramBefore); - model.addAttribute("discover", true); - } else if (paramShow.equals("my") && !visitor.isAnonymous()) { - title = "Моя лента"; - mids = messagesService.getMyFeed(visitor.getUid(), paramBefore, true); - } else if (paramShow.equals("private") && !visitor.isAnonymous()) { - title = "Приватные"; - mids = messagesService.getPrivate(visitor.getUid(), paramBefore); - } else if (paramShow.equals("discuss")) { - return "redirect:/"; - } else if (paramShow.equals("recommended") && !visitor.isAnonymous()) { - title = "Рекомендации"; - mids = messagesService.getRecommended(visitor.getUid(), paramBefore); - } else if (paramShow.equals("photos")) { - title = "Фотографии"; - mids = messagesService.getPhotos(visitor.getUid(), paramBefore); - model.addAttribute("discover", true); - } else if (paramShow.equals("all")) { - title = "Все сообщения"; - mids = messagesService.getAll(visitor.getUid(), paramBefore); - model.addAttribute("discover", true); - } else { - throw new HttpNotFoundException(); - } - - String head = "\n"; - - if (paramBefore > 0 || paramShow != null) { - head = ""; - } - model.addAttribute("title", title); - model.addAttribute("headers", head); - model.addAttribute("visitor", visitor); - model.addAttribute("noindex", !(paramShow == null && paramBefore == 0)); - List msgs = messagesService.getMessages(visitor, mids); - msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); - if (!visitor.isAnonymous()) { - fillUserModel(model, visitor, visitor); - List unread = messagesService.getUnread(visitor); - visitor.setUnreadCount(unread.size()); - List blUIDs = userService.checkBL(visitor.getUid(), - msgs.stream().map(m -> m.getUser().getUid()).collect(Collectors.toList())); - msgs.forEach(m -> m.ReadOnly |= blUIDs.contains(m.getUser().getUid())); - } - model.addAttribute("msgs", msgs); - model.addAttribute("tags", tagService.getPopularTags()); - model.addAttribute("headers", head); - if (mids.size() >= 20) { - String nextpage = paramSearch != null ? String.format("?page=%d", page + 1) - : (paramShow == null) ? "?to=" + msgs.get(msgs.size() - 1).getUpdated().toEpochMilli() - : "?before=" + mids.get(mids.size() - 1); - if (paramShow != null) { - nextpage += "&show=" + paramShow; - } - if (paramSearch != null) { - nextpage += "&search=" + URLEncoder.encode(paramSearch, StandardCharsets.UTF_8); - } - model.addAttribute("nextpage", nextpage); - } - return "views/index"; - } - - @GetMapping(path = "/{uname}/", headers = "Connection!=Upgrade") - protected String doGetBlog( - @Visitor User visitor, - @RequestParam(required = false, name = "show") String paramShow, - @RequestParam(required = false, name = "tag") String paramTagStr, - @RequestParam(required = false, name = "search") String paramSearch, - @RequestParam(required = false, name = "page", defaultValue = "0") Integer page, - @PathVariable String uname, - @RequestParam(required = false, defaultValue = "0") Integer before, - @CookieValue(name = "sape_cookie", required = false, defaultValue = StringUtils.EMPTY) String sapeCookie, - ModelMap model) { - User user = userService.getUserByName(uname); - if (user.isBanned() || user.isAnonymous()) { - throw new HttpNotFoundException(); - } - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - - List mids; - - Tag paramTag = null; - if (paramTagStr != null) { - if (paramTagStr.length() < 64) { - paramTag = tagService.getTag(paramTagStr, false); - } - if (paramTag == null) { - throw new HttpNotFoundException(); - } else if (!paramTag.getName().equals(paramTagStr)) { - String url = user.getName() + "/?tag=" + URLEncoder.encode(paramTag.getName(), StandardCharsets.UTF_8); - return "redirect:/" + url; - } - } - if (paramSearch != null && paramSearch.length() > 64) { - paramSearch = null; - } - - int privacy = 0; - if (!visitor.isAnonymous()) { - if (user.getUid() == visitor.getUid() || visitor.getUid() == 1) { - privacy = -3; - } else if (userService.isInWL(user.getUid(), visitor.getUid())) { - privacy = -2; - } - } - - String title; - if (paramShow == null) { - if (paramTag != null) { - title = "Блог " + user.getName() + ": *" + StringEscapeUtils.escapeHtml4(paramTag.getName()); - mids = messagesService.getUserTag(user.getUid(), paramTag.TID, privacy, before); - } else if (paramSearch != null) { - title = "Блог " + user.getName() + ": " + StringEscapeUtils.escapeHtml4(paramSearch); - mids = messagesService.getUserSearch(visitor, user.getUid(), Utils.encodeSphinx(paramSearch), privacy, page); - } else { - title = "Блог " + user.getName(); - mids = messagesService.getUserBlog(user.getUid(), privacy, before); - } - } else if (paramShow.equals("recomm")) { - title = "Рекомендации " + user.getName(); - mids = messagesService.getUserRecommendations(user.getUid(), before); - } else if (paramShow.equals("photos")) { - title = "Фотографии " + user.getName(); - mids = messagesService.getUserPhotos(user.getUid(), privacy, before); - } else { - throw new HttpNotFoundException(); - } - - String head = ""; - head += "\n"; - if (paramTag != null && tagService.getTagNoIndex(paramTag.TID)) { - head += ""; - } else if (before > 0 || paramShow != null) { - head += ""; - } - model.addAttribute("pageUrl", "http://juick.com/" + user.getName()); - model.addAttribute("title", title); - model.addAttribute("headers", head); - model.addAttribute("visitor", visitor); - model.addAttribute("noindex", paramShow == null && before == 0); - fillUserModel(model, user, visitor); - model.addAttribute("paramTag", paramTag); - List msgs = messagesService.getMessages(visitor, mids); - msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); - if (!visitor.isAnonymous()) { - List unread = messagesService.getUnread(visitor); - visitor.setUnreadCount(unread.size()); - List blUIDs = userService.checkBL(visitor.getUid(), - msgs.stream().map(m -> m.getUser().getUid()).collect(Collectors.toList())); - msgs.forEach(m -> m.ReadOnly |= blUIDs.contains(m.getUser().getUid())); - } - model.addAttribute("msgs", msgs); - model.addAttribute("headers", head); - if (mids.size() >= 20) { - String nextpage = paramSearch != null ? String.format("?page=%d", page + 1) : "?before=" + mids.get(mids.size() - 1); - if (paramShow != null) { - nextpage += "&show=" + paramShow; - } - if (paramSearch != null) { - nextpage += "&search=" + URLEncoder.encode(paramSearch, StandardCharsets.UTF_8); - } - if (paramTag != null) { - nextpage += "&tag=" + URLEncoder.encode(paramTag.getName(), StandardCharsets.UTF_8); - } - model.addAttribute("nextpage", nextpage); - } - return "views/blog"; - } - - @GetMapping("/{uname}/tags") - protected String doGetTags( - @Visitor User visitor, - @PathVariable String uname, ModelMap model) { - User user = userService.getUserByName(uname); - if (visitor.isBanned()) { - throw new HttpNotFoundException(); - } - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - - model.addAttribute("title", "Теги " + user.getName()); - model.addAttribute("headers", ""); - model.addAttribute("visitor", visitor); - fillUserModel(model, user, visitor); - model.addAttribute("tags", tagService.getUserTagStats(user.getUid()).stream() - .sorted((e1, e2) -> Integer.compare(e2.getUsageCount(), e1.getUsageCount())).map(t -> t.getTag().getName()).collect(Collectors.toList())); - - return "views/blog_tags"; - } - - @GetMapping("/{uname}/friends") - protected String doGetFriends( - @Visitor User visitor, - @PathVariable String uname, ModelMap model) { - User user = userService.getUserByName(uname); - if (visitor.isBanned()) { - throw new HttpNotFoundException(); - } - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - model.addAttribute("title", "Подписки " + user.getName()); - model.addAttribute("headers", ""); - model.addAttribute("visitor", visitor); - fillUserModel(model, user, visitor); - model.addAttribute("users", userService.getUserFriends(user.getUid())); - - return "views/users"; - } - - @GetMapping("/{uname}/readers") - protected String doGetReaders( - @Visitor User visitor, - @PathVariable String uname, ModelMap model) { - User user = userService.getUserByName(uname); - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - model.addAttribute("title", "Читатели " + user.getName()); - model.addAttribute("headers", ""); - model.addAttribute("visitor", visitor); - fillUserModel(model, user, visitor); - model.addAttribute("users", userService.getUserReaders(user.getUid())); - - return "views/users"; - } - - @GetMapping("/{uname}/bl") - protected String doGetBL( - @Visitor User visitor, - @PathVariable String uname, ModelMap model) { - User user = userService.getUserByName(uname); - if (visitor.getUid() != user.getUid()) { - throw new HttpForbiddenException(); - } - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - model.addAttribute("title", "Черный список " + user.getName()); - model.addAttribute("headers", ""); - model.addAttribute("visitor", visitor); - fillUserModel(model, user, visitor); - model.addAttribute("users", userService.getUserBLUsers(user.getUid())); - - return "views/users"; - } - @GetMapping("/tag/{tagName}") - protected String tagAction( - @Visitor User visitor, - HttpServletRequest request, - @PathVariable String tagName, - @RequestParam(required = false, defaultValue = "0") int before, - ModelMap model) { - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - String paramTagStr = StringEscapeUtils.unescapeHtml4(tagName); - Tag paramTag = tagService.getTag(paramTagStr, false); - if (paramTag == null) { - throw new HttpNotFoundException(); - } else if (paramTag.SynonymID > 0 && paramTag.TID != paramTag.SynonymID) { - Tag synTag = tagService.getTag(paramTag.SynonymID); - String url = "/tag/" + URLEncoder.encode(StringEscapeUtils.escapeHtml4(synTag.getName()), StandardCharsets.UTF_8); - if (request.getQueryString() != null) { - url += "?" + request.getQueryString(); - } - return "redirect:" + url; - } else if (!paramTag.getName().equals(paramTagStr)) { - String url = "/tag/" + URLEncoder.encode(StringEscapeUtils.escapeHtml4(paramTag.getName()), StandardCharsets.UTF_8); - if (request.getQueryString() != null) { - url += "?" + request.getQueryString(); - } - return "redirect:" + url; - } - - String title = "*" + StringEscapeUtils.escapeHtml4(paramTag.getName()); - model.addAttribute("title", title); - List mids = messagesService.getTag(paramTag.TID, visitor.getUid(), before, (visitor.isAnonymous()) ? 40 : 20); - List msgs = messagesService.getMessages(visitor, mids); - msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); - if (!visitor.isAnonymous()) { - List unread = messagesService.getUnread(visitor); - visitor.setUnreadCount(unread.size()); - List blUIDs = userService.checkBL( - visitor.getUid(), - msgs.stream().map(m -> m.getUser().getUid()).collect(Collectors.toList()) - ); - msgs.forEach(m -> m.ReadOnly |= blUIDs.contains(m.getUser().getUid())); - fillUserModel(model, visitor, visitor); - } - - String head = StringUtils.EMPTY; - if (tagService.getTagNoIndex(paramTag.TID)) { - head = ""; - } else if (before > 0 || mids.size() < 5) { - head = ""; - } - model.addAttribute("headers", head); - model.addAttribute("visitor", visitor); - model.addAttribute("tag", paramTag); - model.addAttribute("title", title); - model.addAttribute("msgs", msgs); - model.addAttribute("tags", tagService.getPopularTags()); - model.addAttribute("noindex", before > 0); - model.addAttribute("isSubscribed", tagService.isSubscribed(visitor, paramTag)); - model.addAttribute("isInBL", tagService.isInBL(visitor, paramTag)); - if (mids.size() >= 20) { - String nextpage = "/tag/" + URLEncoder.encode(paramTag.getName(), StandardCharsets.UTF_8) + "?before=" + mids.get(mids.size() - 1); - model.addAttribute("nextpage", nextpage); - } - return "views/index"; - } - @GetMapping("/pm/inbox") - protected String doGetInbox(@Visitor User visitor, ModelMap model) { - if (visitor.isAnonymous()) { - return "redirect:/login"; - } - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - String title = "PM: Inbox"; - List msgs = pmQueriesService.getLastPMInbox(visitor.getUid()); - msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); - fillUserModel(model, visitor, visitor); - model.addAttribute("title", title); - model.addAttribute("visitor", visitor); - model.addAttribute("msgs", msgs); - model.addAttribute("tags", tagService.getPopularTags()); - return "views/pm_inbox"; - } - - @GetMapping("/pm/sent") - protected String doGetSent( - @Visitor User visitor, - @RequestParam(required = false) String uname, - ModelMap model) { - if (visitor.isAnonymous()) { - return "redirect:/login"; - } - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - String title = "PM: Sent"; - List msgs = pmQueriesService.getLastPMSent(visitor.getUid()); - msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); - if (WebUtils.isNotUserName(uname)) { - uname = StringUtils.EMPTY; - } - fillUserModel(model, visitor, visitor); - model.addAttribute("title", title); - model.addAttribute("visitor", visitor); - model.addAttribute("msgs", msgs); - model.addAttribute("tags", tagService.getPopularTags()); - model.addAttribute("uname", uname); - return "views/pm_sent"; - } - @GetMapping(value = "/{uname}/{mid}", produces = MediaType.TEXT_HTML_VALUE) - protected String threadAction( - @Visitor User visitor, - ModelMap model, - @PathVariable String uname, - @PathVariable int mid, - @CookieValue(name = "sape_cookie", required = false, defaultValue = StringUtils.EMPTY) String sapeCookie) { - if (!messagesService.canViewThread(mid, visitor.getUid())) { - throw new HttpForbiddenException(); - } - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - Optional message = messagesService.getMessage(mid); - - if (message.isEmpty()) { - throw new HttpNotFoundException(); - } - - Message msg = message.get(); - - User user = userService.getUserByName(uname); - if (user.isAnonymous() || !msg.getUser().equals(user)) { - return String.format("redirect:/%s/%d", msg.getUser().getName(), mid); - } - msg.VisitorCanComment = !visitor.isAnonymous(); - msg.getUser().setAvatar(webApp.getAvatarWebPath(msg.getUser())); - List replies = messagesService.getReplies(visitor, msg.getMid()); - // this should be after getReplies to mark thread as read - fillUserModel(model, user, visitor); - if (!visitor.isAnonymous()) { - List unread = messagesService.getUnread(visitor); - visitor.setUnreadCount(unread.size()); - boolean isMsgAuthor = visitor.getUid() == msg.getUser().getUid(); - boolean isInBL = userService.isInBLAny(msg.getUser().getUid(), visitor.getUid()); - msg.VisitorCanComment = isMsgAuthor || !(msg.ReadOnly || isInBL); - } - model.addAttribute("msg", msg); - - String title = msg.getUser().getName() + ": " + MessageUtils.getTagsString(msg); - - model.addAttribute("title", title); - model.addAttribute("visitor", visitor); - String headers = ""; - String pageUrl = "https://juick.com/" + msg.getUser().getName() + "/" + msg.getMid(); - if (msg.Hidden) { - headers += ""; - } - String cardType = StringUtils.isNotEmpty(msg.getAttachmentType()) ? "summary_large_image" : "summary"; - if (StringUtils.isNotEmpty(msg.getAttachmentType())) { - // additional check in case of broken images - if (msg.getAttachment() != null) { - String msgImage = msg.getAttachment().getMedium().getUrl(); - headers += ""; - } - } else { - String msgImage = webApp.getAvatarWebPath(msg.getUser()); - headers += ""; - } - model.addAttribute("ogtype", "article"); - String cardDescription = StringEscapeUtils.escapeHtml4(PlainTextFormatter.formatTwitterCard(msg)); - headers += "\n" + - "\n" + - "\n" + - "\n" + - "\n" + - "\n"; - String twitterName = crosspostService.getTwitterName(msg.getUser().getUid()); - if (StringUtils.isNotEmpty(twitterName)) { - headers += "\n"; - } - if (msg.getTags().size() > 0) { - headers += "\n"; - } - model.addAttribute("headers", headers); - model.addAttribute("visitorSubscribed", messagesService.isSubscribed(visitor.getUid(), msg.getMid())); - model.addAttribute("visitorInBL", userService.isInBL(msg.getUser().getUid(), visitor.getUid())); - model.addAttribute("recomm", messagesService.getMessagesRecommendations( - Collections.singletonList(msg.getMid())).stream() - .map(Pair::getRight).collect(Collectors.toList())); - List blUIDs = new ArrayList<>(); - for (Message reply : replies) { - if (reply.getUser().getUid() != msg.getUser().getUid() - && !blUIDs.contains(reply.getUser().getUid())) { - blUIDs.add(reply.getUser().getUid()); - } - reply.VisitorCanComment = !visitor.isAnonymous(); - reply.getUser().setAvatar(webApp.getAvatarWebPath(reply.getUser())); - if (!visitor.isAnonymous()) { - boolean isMsgAuthor = visitor.getUid() == msg.getUser().getUid(); - boolean isReplyAuthor = visitor.getUid() == reply.getUser().getUid(); - reply.VisitorCanComment = isMsgAuthor || (!msg.ReadOnly - && msg.VisitorCanComment && (isReplyAuthor || !userService.isInBLAny(visitor.getUid(), reply.getUser().getUid()))); - } - } - model.addAttribute("replies", replies); - return "views/thread"; - } - - @GetMapping("/post") - protected String postAction( - @Visitor User visitor, - @RequestParam(required = false) String body, ModelMap model) { - fillUserModel(model, visitor, visitor); - visitor.setAvatar(webApp.getAvatarWebPath(visitor)); - model.addAttribute("title", "Написать"); - model.addAttribute("headers", ""); - model.addAttribute("visitor", visitor); - if (body == null) { - body = StringUtils.EMPTY; - } else { - if (body.length() > 4096) { - body = body.substring(0, 4096); - } - body = StringEscapeUtils.escapeHtml4(body); - } - model.addAttribute("body", body); - model.addAttribute("visitor", visitor); - model.addAttribute("user", visitor); - model.addAttribute("tags", tagService.getUserTagStats(visitor.getUid()).stream() - .sorted((e1, e2) -> Integer.compare(e2.getUsageCount(), e1.getUsageCount())).map(t -> t.getTag().getName()).collect(Collectors.toList())); - return "views/post"; - } - - // when message id is not fit to int - @ExceptionHandler(NumberFormatException.class) - public ResponseEntity notFoundAction() { - return new ResponseEntity<>(HttpStatus.NOT_FOUND); - } -} diff --git a/src/main/java/com/juick/www/controllers/Site.java b/src/main/java/com/juick/www/controllers/Site.java new file mode 100644 index 00000000..61b84f71 --- /dev/null +++ b/src/main/java/com/juick/www/controllers/Site.java @@ -0,0 +1,590 @@ +/* + * Copyright (C) 2008-2019, Juick + * + * 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 . + */ +package com.juick.www.controllers; + +import com.juick.model.Message; +import com.juick.model.Tag; +import com.juick.model.User; +import com.juick.formatters.PlainTextFormatter; +import com.juick.server.Utils; +import com.juick.server.util.HttpForbiddenException; +import com.juick.server.util.HttpNotFoundException; +import com.juick.server.util.WebUtils; +import com.juick.www.WebApp; +import com.juick.service.*; +import com.juick.service.security.annotation.Visitor; +import com.juick.util.MessageUtils; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.apache.commons.text.StringEscapeUtils; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.*; + +import javax.inject.Inject; +import javax.servlet.http.HttpServletRequest; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * + * @author Ugnich Anton + */ +@Controller +public class Site { + @Inject + private UserService userService; + @Inject + private TagService tagService; + @Inject + private MessagesService messagesService; + @Inject + private PMQueriesService pmQueriesService; + @Inject + private CrosspostService crosspostService; + @Inject + private WebApp webApp; + + private void fillUserModel(ModelMap model, User user, User visitor) { + user.setAvatar(webApp.getAvatarWebPath(user)); + model.addAttribute("user", user); + model.addAttribute("isSubscribed", userService.isSubscribed(visitor.getUid(), user.getUid())); + model.addAttribute("isInBL", userService.isInBL(visitor.getUid(), user.getUid())); + model.addAttribute("isInBLAny", userService.isInBLAny(user.getUid(), visitor.getUid())); + model.addAttribute("statsIRead", userService.getUserFriends(user.getUid()).size()); + model.addAttribute("statsMyReaders", userService.getStatsMyReaders(user.getUid())); + model.addAttribute("statsMyBL", userService.getUserBLUsers(user.getUid()).size()); + model.addAttribute("statsMessages", userService.getStatsMessages(user.getUid())); + model.addAttribute("statsReplies", userService.getStatsReplies(user.getUid())); + model.addAttribute("iread", userService.getUserReadLeastPopular(user.getUid(), 8)); + model.addAttribute("tagStats", tagService.getUserTagStats(user.getUid()) + .stream().sorted((e1, e2) -> Integer.compare(e2.getUsageCount(), e1.getUsageCount())).limit(20).map(t -> t.getTag().getName()).collect(Collectors.toList())); + } + + @GetMapping("/") + protected String doGet( + @Visitor User visitor, + @RequestParam(required = false) String tag, + @RequestParam(name = "show", required = false) String paramShow, + @RequestParam(name = "search", required = false) String paramSearch, + @RequestParam(name = "before", required = false, defaultValue = "0") Integer paramBefore, + @RequestParam(name = "to", required = false, defaultValue = "0") Long paramTo, + @RequestParam(name = "page", required = false, defaultValue = "0") Integer page, + ModelMap model) { + if (tag != null) { + return "redirect:/tag/" + URLEncoder.encode(tag, StandardCharsets.UTF_8); + } + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + + if (paramSearch != null && paramSearch.length() > 64) { + paramSearch = null; + } + + model.addAttribute("discover", false); + + String title; + List mids; + + if (paramSearch != null) { + title = "Поиск: " + StringEscapeUtils.escapeHtml4(paramSearch); + mids = messagesService.getSearch(visitor, Utils.encodeSphinx(paramSearch), page); + } else if (paramShow == null) { + title = "Обсуждения"; + mids = messagesService.getDiscussions(visitor.getUid(), paramTo); + } else if (paramShow.equals("top")) { + title = "Популярные"; + mids = messagesService.getPopular(visitor.getUid(), paramBefore); + model.addAttribute("discover", true); + } else if (paramShow.equals("my") && !visitor.isAnonymous()) { + title = "Моя лента"; + mids = messagesService.getMyFeed(visitor.getUid(), paramBefore, true); + } else if (paramShow.equals("private") && !visitor.isAnonymous()) { + title = "Приватные"; + mids = messagesService.getPrivate(visitor.getUid(), paramBefore); + } else if (paramShow.equals("discuss")) { + return "redirect:/"; + } else if (paramShow.equals("recommended") && !visitor.isAnonymous()) { + title = "Рекомендации"; + mids = messagesService.getRecommended(visitor.getUid(), paramBefore); + } else if (paramShow.equals("photos")) { + title = "Фотографии"; + mids = messagesService.getPhotos(visitor.getUid(), paramBefore); + model.addAttribute("discover", true); + } else if (paramShow.equals("all")) { + title = "Все сообщения"; + mids = messagesService.getAll(visitor.getUid(), paramBefore); + model.addAttribute("discover", true); + } else { + throw new HttpNotFoundException(); + } + + String head = "\n"; + + if (paramBefore > 0 || paramShow != null) { + head = ""; + } + model.addAttribute("title", title); + model.addAttribute("headers", head); + model.addAttribute("visitor", visitor); + model.addAttribute("noindex", !(paramShow == null && paramBefore == 0)); + List msgs = messagesService.getMessages(visitor, mids); + msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); + if (!visitor.isAnonymous()) { + fillUserModel(model, visitor, visitor); + List unread = messagesService.getUnread(visitor); + visitor.setUnreadCount(unread.size()); + List blUIDs = userService.checkBL(visitor.getUid(), + msgs.stream().map(m -> m.getUser().getUid()).collect(Collectors.toList())); + msgs.forEach(m -> m.ReadOnly |= blUIDs.contains(m.getUser().getUid())); + } + model.addAttribute("msgs", msgs); + model.addAttribute("tags", tagService.getPopularTags()); + model.addAttribute("headers", head); + if (mids.size() >= 20) { + String nextpage = paramSearch != null ? String.format("?page=%d", page + 1) + : (paramShow == null) ? "?to=" + msgs.get(msgs.size() - 1).getUpdated().toEpochMilli() + : "?before=" + mids.get(mids.size() - 1); + if (paramShow != null) { + nextpage += "&show=" + paramShow; + } + if (paramSearch != null) { + nextpage += "&search=" + URLEncoder.encode(paramSearch, StandardCharsets.UTF_8); + } + model.addAttribute("nextpage", nextpage); + } + return "views/index"; + } + + @GetMapping(path = "/{uname}/", headers = "Connection!=Upgrade") + protected String doGetBlog( + @Visitor User visitor, + @RequestParam(required = false, name = "show") String paramShow, + @RequestParam(required = false, name = "tag") String paramTagStr, + @RequestParam(required = false, name = "search") String paramSearch, + @RequestParam(required = false, name = "page", defaultValue = "0") Integer page, + @PathVariable String uname, + @RequestParam(required = false, defaultValue = "0") Integer before, + @CookieValue(name = "sape_cookie", required = false, defaultValue = StringUtils.EMPTY) String sapeCookie, + ModelMap model) { + User user = userService.getUserByName(uname); + if (user.isBanned() || user.isAnonymous()) { + throw new HttpNotFoundException(); + } + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + + List mids; + + Tag paramTag = null; + if (paramTagStr != null) { + if (paramTagStr.length() < 64) { + paramTag = tagService.getTag(paramTagStr, false); + } + if (paramTag == null) { + throw new HttpNotFoundException(); + } else if (!paramTag.getName().equals(paramTagStr)) { + String url = user.getName() + "/?tag=" + URLEncoder.encode(paramTag.getName(), StandardCharsets.UTF_8); + return "redirect:/" + url; + } + } + if (paramSearch != null && paramSearch.length() > 64) { + paramSearch = null; + } + + int privacy = 0; + if (!visitor.isAnonymous()) { + if (user.getUid() == visitor.getUid() || visitor.getUid() == 1) { + privacy = -3; + } else if (userService.isInWL(user.getUid(), visitor.getUid())) { + privacy = -2; + } + } + + String title; + if (paramShow == null) { + if (paramTag != null) { + title = "Блог " + user.getName() + ": *" + StringEscapeUtils.escapeHtml4(paramTag.getName()); + mids = messagesService.getUserTag(user.getUid(), paramTag.TID, privacy, before); + } else if (paramSearch != null) { + title = "Блог " + user.getName() + ": " + StringEscapeUtils.escapeHtml4(paramSearch); + mids = messagesService.getUserSearch(visitor, user.getUid(), Utils.encodeSphinx(paramSearch), privacy, page); + } else { + title = "Блог " + user.getName(); + mids = messagesService.getUserBlog(user.getUid(), privacy, before); + } + } else if (paramShow.equals("recomm")) { + title = "Рекомендации " + user.getName(); + mids = messagesService.getUserRecommendations(user.getUid(), before); + } else if (paramShow.equals("photos")) { + title = "Фотографии " + user.getName(); + mids = messagesService.getUserPhotos(user.getUid(), privacy, before); + } else { + throw new HttpNotFoundException(); + } + + String head = ""; + head += "\n"; + if (paramTag != null && tagService.getTagNoIndex(paramTag.TID)) { + head += ""; + } else if (before > 0 || paramShow != null) { + head += ""; + } + model.addAttribute("pageUrl", "http://juick.com/" + user.getName()); + model.addAttribute("title", title); + model.addAttribute("headers", head); + model.addAttribute("visitor", visitor); + model.addAttribute("noindex", paramShow == null && before == 0); + fillUserModel(model, user, visitor); + model.addAttribute("paramTag", paramTag); + List msgs = messagesService.getMessages(visitor, mids); + msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); + if (!visitor.isAnonymous()) { + List unread = messagesService.getUnread(visitor); + visitor.setUnreadCount(unread.size()); + List blUIDs = userService.checkBL(visitor.getUid(), + msgs.stream().map(m -> m.getUser().getUid()).collect(Collectors.toList())); + msgs.forEach(m -> m.ReadOnly |= blUIDs.contains(m.getUser().getUid())); + } + model.addAttribute("msgs", msgs); + model.addAttribute("headers", head); + if (mids.size() >= 20) { + String nextpage = paramSearch != null ? String.format("?page=%d", page + 1) : "?before=" + mids.get(mids.size() - 1); + if (paramShow != null) { + nextpage += "&show=" + paramShow; + } + if (paramSearch != null) { + nextpage += "&search=" + URLEncoder.encode(paramSearch, StandardCharsets.UTF_8); + } + if (paramTag != null) { + nextpage += "&tag=" + URLEncoder.encode(paramTag.getName(), StandardCharsets.UTF_8); + } + model.addAttribute("nextpage", nextpage); + } + return "views/blog"; + } + + @GetMapping("/{uname}/tags") + protected String doGetTags( + @Visitor User visitor, + @PathVariable String uname, ModelMap model) { + User user = userService.getUserByName(uname); + if (visitor.isBanned()) { + throw new HttpNotFoundException(); + } + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + + model.addAttribute("title", "Теги " + user.getName()); + model.addAttribute("headers", ""); + model.addAttribute("visitor", visitor); + fillUserModel(model, user, visitor); + model.addAttribute("tags", tagService.getUserTagStats(user.getUid()).stream() + .sorted((e1, e2) -> Integer.compare(e2.getUsageCount(), e1.getUsageCount())).map(t -> t.getTag().getName()).collect(Collectors.toList())); + + return "views/blog_tags"; + } + + @GetMapping("/{uname}/friends") + protected String doGetFriends( + @Visitor User visitor, + @PathVariable String uname, ModelMap model) { + User user = userService.getUserByName(uname); + if (visitor.isBanned()) { + throw new HttpNotFoundException(); + } + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + model.addAttribute("title", "Подписки " + user.getName()); + model.addAttribute("headers", ""); + model.addAttribute("visitor", visitor); + fillUserModel(model, user, visitor); + model.addAttribute("users", userService.getUserFriends(user.getUid())); + + return "views/users"; + } + + @GetMapping("/{uname}/readers") + protected String doGetReaders( + @Visitor User visitor, + @PathVariable String uname, ModelMap model) { + User user = userService.getUserByName(uname); + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + model.addAttribute("title", "Читатели " + user.getName()); + model.addAttribute("headers", ""); + model.addAttribute("visitor", visitor); + fillUserModel(model, user, visitor); + model.addAttribute("users", userService.getUserReaders(user.getUid())); + + return "views/users"; + } + + @GetMapping("/{uname}/bl") + protected String doGetBL( + @Visitor User visitor, + @PathVariable String uname, ModelMap model) { + User user = userService.getUserByName(uname); + if (visitor.getUid() != user.getUid()) { + throw new HttpForbiddenException(); + } + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + model.addAttribute("title", "Черный список " + user.getName()); + model.addAttribute("headers", ""); + model.addAttribute("visitor", visitor); + fillUserModel(model, user, visitor); + model.addAttribute("users", userService.getUserBLUsers(user.getUid())); + + return "views/users"; + } + @GetMapping("/tag/{tagName}") + protected String tagAction( + @Visitor User visitor, + HttpServletRequest request, + @PathVariable String tagName, + @RequestParam(required = false, defaultValue = "0") int before, + ModelMap model) { + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + String paramTagStr = StringEscapeUtils.unescapeHtml4(tagName); + Tag paramTag = tagService.getTag(paramTagStr, false); + if (paramTag == null) { + throw new HttpNotFoundException(); + } else if (paramTag.SynonymID > 0 && paramTag.TID != paramTag.SynonymID) { + Tag synTag = tagService.getTag(paramTag.SynonymID); + String url = "/tag/" + URLEncoder.encode(StringEscapeUtils.escapeHtml4(synTag.getName()), StandardCharsets.UTF_8); + if (request.getQueryString() != null) { + url += "?" + request.getQueryString(); + } + return "redirect:" + url; + } else if (!paramTag.getName().equals(paramTagStr)) { + String url = "/tag/" + URLEncoder.encode(StringEscapeUtils.escapeHtml4(paramTag.getName()), StandardCharsets.UTF_8); + if (request.getQueryString() != null) { + url += "?" + request.getQueryString(); + } + return "redirect:" + url; + } + + String title = "*" + StringEscapeUtils.escapeHtml4(paramTag.getName()); + model.addAttribute("title", title); + List mids = messagesService.getTag(paramTag.TID, visitor.getUid(), before, (visitor.isAnonymous()) ? 40 : 20); + List msgs = messagesService.getMessages(visitor, mids); + msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); + if (!visitor.isAnonymous()) { + List unread = messagesService.getUnread(visitor); + visitor.setUnreadCount(unread.size()); + List blUIDs = userService.checkBL( + visitor.getUid(), + msgs.stream().map(m -> m.getUser().getUid()).collect(Collectors.toList()) + ); + msgs.forEach(m -> m.ReadOnly |= blUIDs.contains(m.getUser().getUid())); + fillUserModel(model, visitor, visitor); + } + + String head = StringUtils.EMPTY; + if (tagService.getTagNoIndex(paramTag.TID)) { + head = ""; + } else if (before > 0 || mids.size() < 5) { + head = ""; + } + model.addAttribute("headers", head); + model.addAttribute("visitor", visitor); + model.addAttribute("tag", paramTag); + model.addAttribute("title", title); + model.addAttribute("msgs", msgs); + model.addAttribute("tags", tagService.getPopularTags()); + model.addAttribute("noindex", before > 0); + model.addAttribute("isSubscribed", tagService.isSubscribed(visitor, paramTag)); + model.addAttribute("isInBL", tagService.isInBL(visitor, paramTag)); + if (mids.size() >= 20) { + String nextpage = "/tag/" + URLEncoder.encode(paramTag.getName(), StandardCharsets.UTF_8) + "?before=" + mids.get(mids.size() - 1); + model.addAttribute("nextpage", nextpage); + } + return "views/index"; + } + @GetMapping("/pm/inbox") + protected String doGetInbox(@Visitor User visitor, ModelMap model) { + if (visitor.isAnonymous()) { + return "redirect:/login"; + } + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + String title = "PM: Inbox"; + List msgs = pmQueriesService.getLastPMInbox(visitor.getUid()); + msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); + fillUserModel(model, visitor, visitor); + model.addAttribute("title", title); + model.addAttribute("visitor", visitor); + model.addAttribute("msgs", msgs); + model.addAttribute("tags", tagService.getPopularTags()); + return "views/pm_inbox"; + } + + @GetMapping("/pm/sent") + protected String doGetSent( + @Visitor User visitor, + @RequestParam(required = false) String uname, + ModelMap model) { + if (visitor.isAnonymous()) { + return "redirect:/login"; + } + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + String title = "PM: Sent"; + List msgs = pmQueriesService.getLastPMSent(visitor.getUid()); + msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarWebPath(m.getUser()))); + if (WebUtils.isNotUserName(uname)) { + uname = StringUtils.EMPTY; + } + fillUserModel(model, visitor, visitor); + model.addAttribute("title", title); + model.addAttribute("visitor", visitor); + model.addAttribute("msgs", msgs); + model.addAttribute("tags", tagService.getPopularTags()); + model.addAttribute("uname", uname); + return "views/pm_sent"; + } + @GetMapping(value = "/{uname}/{mid}", produces = MediaType.TEXT_HTML_VALUE) + protected String threadAction( + @Visitor User visitor, + ModelMap model, + @PathVariable String uname, + @PathVariable int mid, + @CookieValue(name = "sape_cookie", required = false, defaultValue = StringUtils.EMPTY) String sapeCookie) { + if (!messagesService.canViewThread(mid, visitor.getUid())) { + throw new HttpForbiddenException(); + } + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + Optional message = messagesService.getMessage(mid); + + if (message.isEmpty()) { + throw new HttpNotFoundException(); + } + + Message msg = message.get(); + + User user = userService.getUserByName(uname); + if (user.isAnonymous() || !msg.getUser().equals(user)) { + return String.format("redirect:/%s/%d", msg.getUser().getName(), mid); + } + msg.VisitorCanComment = !visitor.isAnonymous(); + msg.getUser().setAvatar(webApp.getAvatarWebPath(msg.getUser())); + List replies = messagesService.getReplies(visitor, msg.getMid()); + // this should be after getReplies to mark thread as read + fillUserModel(model, user, visitor); + if (!visitor.isAnonymous()) { + List unread = messagesService.getUnread(visitor); + visitor.setUnreadCount(unread.size()); + boolean isMsgAuthor = visitor.getUid() == msg.getUser().getUid(); + boolean isInBL = userService.isInBLAny(msg.getUser().getUid(), visitor.getUid()); + msg.VisitorCanComment = isMsgAuthor || !(msg.ReadOnly || isInBL); + } + model.addAttribute("msg", msg); + + String title = msg.getUser().getName() + ": " + MessageUtils.getTagsString(msg); + + model.addAttribute("title", title); + model.addAttribute("visitor", visitor); + String headers = ""; + String pageUrl = "https://juick.com/" + msg.getUser().getName() + "/" + msg.getMid(); + if (msg.Hidden) { + headers += ""; + } + String cardType = StringUtils.isNotEmpty(msg.getAttachmentType()) ? "summary_large_image" : "summary"; + if (StringUtils.isNotEmpty(msg.getAttachmentType())) { + // additional check in case of broken images + if (msg.getAttachment() != null) { + String msgImage = msg.getAttachment().getMedium().getUrl(); + headers += ""; + } + } else { + String msgImage = webApp.getAvatarWebPath(msg.getUser()); + headers += ""; + } + model.addAttribute("ogtype", "article"); + String cardDescription = StringEscapeUtils.escapeHtml4(PlainTextFormatter.formatTwitterCard(msg)); + headers += "\n" + + "\n" + + "\n" + + "\n" + + "\n" + + "\n"; + String twitterName = crosspostService.getTwitterName(msg.getUser().getUid()); + if (StringUtils.isNotEmpty(twitterName)) { + headers += "\n"; + } + if (msg.getTags().size() > 0) { + headers += "\n"; + } + model.addAttribute("headers", headers); + model.addAttribute("visitorSubscribed", messagesService.isSubscribed(visitor.getUid(), msg.getMid())); + model.addAttribute("visitorInBL", userService.isInBL(msg.getUser().getUid(), visitor.getUid())); + model.addAttribute("recomm", messagesService.getMessagesRecommendations( + Collections.singletonList(msg.getMid())).stream() + .map(Pair::getRight).collect(Collectors.toList())); + List blUIDs = new ArrayList<>(); + for (Message reply : replies) { + if (reply.getUser().getUid() != msg.getUser().getUid() + && !blUIDs.contains(reply.getUser().getUid())) { + blUIDs.add(reply.getUser().getUid()); + } + reply.VisitorCanComment = !visitor.isAnonymous(); + reply.getUser().setAvatar(webApp.getAvatarWebPath(reply.getUser())); + if (!visitor.isAnonymous()) { + boolean isMsgAuthor = visitor.getUid() == msg.getUser().getUid(); + boolean isReplyAuthor = visitor.getUid() == reply.getUser().getUid(); + reply.VisitorCanComment = isMsgAuthor || (!msg.ReadOnly + && msg.VisitorCanComment && (isReplyAuthor || !userService.isInBLAny(visitor.getUid(), reply.getUser().getUid()))); + } + } + model.addAttribute("replies", replies); + return "views/thread"; + } + + @GetMapping("/post") + protected String postAction( + @Visitor User visitor, + @RequestParam(required = false) String body, ModelMap model) { + fillUserModel(model, visitor, visitor); + visitor.setAvatar(webApp.getAvatarWebPath(visitor)); + model.addAttribute("title", "Написать"); + model.addAttribute("headers", ""); + model.addAttribute("visitor", visitor); + if (body == null) { + body = StringUtils.EMPTY; + } else { + if (body.length() > 4096) { + body = body.substring(0, 4096); + } + body = StringEscapeUtils.escapeHtml4(body); + } + model.addAttribute("body", body); + model.addAttribute("visitor", visitor); + model.addAttribute("user", visitor); + model.addAttribute("tags", tagService.getUserTagStats(visitor.getUid()).stream() + .sorted((e1, e2) -> Integer.compare(e2.getUsageCount(), e1.getUsageCount())).map(t -> t.getTag().getName()).collect(Collectors.toList())); + return "views/post"; + } + + // when message id is not fit to int + @ExceptionHandler(NumberFormatException.class) + public ResponseEntity notFoundAction() { + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } +} -- cgit v1.2.3