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/api/Messages.java | 217 ++++++++++++++++++++++++++ 1 file changed, 217 insertions(+) create mode 100644 src/main/java/com/juick/www/api/Messages.java (limited to 'src/main/java/com/juick/www/api/Messages.java') diff --git a/src/main/java/com/juick/www/api/Messages.java b/src/main/java/com/juick/www/api/Messages.java new file mode 100644 index 00000000..59ed7c8f --- /dev/null +++ b/src/main/java/com/juick/www/api/Messages.java @@ -0,0 +1,217 @@ +/* + * 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.api; + +import com.juick.model.Message; +import com.juick.model.Tag; +import com.juick.model.User; +import com.juick.server.Utils; +import com.juick.www.WebApp; +import com.juick.model.CommandResult; +import com.juick.server.util.HttpBadRequestException; +import com.juick.service.MessagesService; +import com.juick.service.TagService; +import com.juick.service.UserService; +import com.juick.service.component.SystemEvent; +import com.juick.service.security.annotation.Visitor; +import org.apache.commons.io.IOUtils; +import org.apache.commons.lang3.tuple.Pair; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationEventPublisher; +import org.springframework.core.io.Resource; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.util.StringUtils; +import org.springframework.web.bind.annotation.*; + +import javax.inject.Inject; +import java.io.IOException; +import java.util.*; +import java.util.stream.Collectors; + +/** + * @author ugnich + */ +@RestController +@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE) +public class Messages { + + private static final ResponseEntity> NOT_FOUND = ResponseEntity + .status(HttpStatus.NOT_FOUND) + .body(Collections.emptyList()); + + private static final ResponseEntity> FORBIDDEN = ResponseEntity + .status(HttpStatus.FORBIDDEN) + .body(Collections.emptyList()); + + @Inject + private MessagesService messagesService; + @Inject + private UserService userService; + @Inject + private TagService tagService; + @Inject + private ApplicationEventPublisher applicationEventPublisher; + @Inject + private WebApp webApp; + @Value("classpath:Transparent.gif") + private Resource invisiblePixel; + + // TODO: serialize image urls + + @GetMapping("/api/home") + public ResponseEntity> getHome( + @Visitor User visitor, + @RequestParam(defaultValue = "0") int before_mid) { + if (!visitor.isAnonymous()) { + int vuid = visitor.getUid(); + List mids = messagesService.getMyFeed(vuid, before_mid, true); + List msgs = messagesService.getMessages(visitor, mids); + msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarUrl(m.getUser()))); + return ResponseEntity.ok(msgs); + } + return FORBIDDEN; + } + + @GetMapping("/api/messages") + public ResponseEntity> getMessages( + @Visitor User visitor, + @RequestParam(required = false) String uname, + @RequestParam(name = "before_mid", defaultValue = "0") Integer before, + @RequestParam(required = false, defaultValue = "0") Integer daysback, + @RequestParam(required = false) String withrecommended, + @RequestParam(required = false) String popular, + @RequestParam(required = false) String search, + @RequestParam(required = false, defaultValue = "0") Integer page, + @RequestParam(required = false) String media, + @RequestParam(required = false) String tag) { + List mids; + if (!StringUtils.isEmpty(uname)) { + User user = userService.getUserByName(uname); + if (!user.isAnonymous() && !user.isBanned()) { + if (!StringUtils.isEmpty(media)) { + mids = messagesService.getUserPhotos(user.getUid(), 0, before); + } else if (!StringUtils.isEmpty(tag)) { + Tag tagObject = tagService.getTag(tag, false); + if (tagObject != null) { + mids = messagesService.getUserTag(user.getUid(), tagObject.TID, 0, before); + } else { + return NOT_FOUND; + } + } else if (!StringUtils.isEmpty(withrecommended)) { + mids = messagesService.getUserBlogWithRecommendations(user.getUid(), 0, before); + } else if (daysback > 0) { + mids = messagesService.getUserBlogAtDay(user.getUid(), 0, daysback); + } else if (!StringUtils.isEmpty(search)) { + mids = messagesService.getUserSearch(visitor, user.getUid(), Utils.encodeSphinx(search), 0, page); + } else { + mids = messagesService.getUserBlog(user.getUid(), 0, before); + } + } else { + return NOT_FOUND; + } + } else { + if (!StringUtils.isEmpty(popular)) { + mids = messagesService.getPopular(visitor.getUid(), before); + } else if (!StringUtils.isEmpty(media)) { + mids = messagesService.getPhotos(visitor.getUid(), before); + } else if (!StringUtils.isEmpty(tag)) { + Tag tagObject = tagService.getTag(tag, false); + if (tagObject != null) { + mids = messagesService.getTag(tagObject.TID, visitor.getUid(), before, 20); + } else { + return NOT_FOUND; + } + } else if (!StringUtils.isEmpty(search)) { + mids = messagesService.getSearch(visitor, Utils.encodeSphinx(search), page); + } else { + mids = messagesService.getAll(visitor.getUid(), before); + } + } + List msgs = messagesService.getMessages(visitor, mids); + msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarUrl(m.getUser()))); + return ResponseEntity.ok(msgs); + } + @DeleteMapping("/api/messages") + public CommandResult deleteMessage( + @Visitor User visitor, + @RequestParam int mid, @RequestParam(required = false, defaultValue = "0") int rid) { + if (rid > 0) { + if (messagesService.deleteReply(visitor.getUid(), mid, rid)) { + return CommandResult.fromString("Reply deleted"); + } + } + if (messagesService.deleteMessage(visitor.getUid(), mid)) { + return CommandResult.fromString("Message deleted"); + } + throw new HttpBadRequestException(); + } + + @GetMapping("/api/messages/discussions") + public List getDiscussions( + @Visitor User visitor, + @RequestParam(required = false, defaultValue = "0") Long to) { + List msgs = messagesService.getMessages(visitor, + messagesService.getDiscussions(visitor.getUid(), to)); + msgs.forEach(m -> m.getUser().setAvatar(webApp.getAvatarUrl(m.getUser()))); + return msgs; + } + @GetMapping("/api/thread") + public ResponseEntity> getThread( + @Visitor User visitor, + @RequestParam(defaultValue = "0") int mid) { + Optional message = messagesService.getMessage(mid); + if (message.isPresent()) { + Message msg = message.get(); + if (!messagesService.canViewThread(mid, visitor.getUid())) { + return FORBIDDEN; + } else { + msg.getUser().setAvatar(webApp.getAvatarUrl(msg.getUser())); + msg.setRecommendations(new HashSet<>(messagesService.getMessagesRecommendations( + Collections.singletonList(msg.getMid())) + .stream().map(Pair::getRight).collect(Collectors.toList()))); + msg.getRecommendations().forEach(r -> r.setAvatar(webApp.getAvatarUrl(r))); + List replies = messagesService.getReplies(visitor, mid); + replies.forEach(m -> m.getUser().setAvatar(webApp.getAvatarUrl(m.getUser()))); + if (!visitor.isAnonymous()) { + userService.updateLastSeen(visitor); + applicationEventPublisher.publishEvent( + new SystemEvent(this, SystemActivity.read(visitor, msg))); + } + replies.add(0, msg); + return ResponseEntity.ok(replies); + } + } + return NOT_FOUND; + } + @GetMapping(value = "/api/thread/mark_read/{mid}-{rid}.gif", produces = MediaType.IMAGE_GIF_VALUE) + public byte[] markThreadRead( + @Visitor User visitor, + @PathVariable int mid, @PathVariable int rid) throws IOException { + if (!visitor.isAnonymous()) { + messagesService.setLastReadComment(visitor, mid, rid); + Message msg = messagesService.getMessage(mid).orElseThrow(IllegalStateException::new); + userService.updateLastSeen(visitor); + applicationEventPublisher.publishEvent( + new SystemEvent(this, SystemActivity.read(visitor, msg))); + return IOUtils.toByteArray(invisiblePixel.getInputStream()); + } + throw new HttpBadRequestException(); + } +} -- cgit v1.2.3