aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/com/juick/www/api/Messages.java
diff options
context:
space:
mode:
authorGravatar Vitaly Takmazov2020-04-03 23:53:23 +0300
committerGravatar Vitaly Takmazov2020-04-03 23:53:23 +0300
commit7a2f89266c8f6337e4e81a2fd8488e0f80f4f9bd (patch)
tree3b83cf2edb18b224e6e0b7924624310d68acc93a /src/main/java/com/juick/www/api/Messages.java
parent1b93e5b16ee5bc7253f3b06639fb9e9abb46acd0 (diff)
Reorganize layout and code cleanup
Diffstat (limited to 'src/main/java/com/juick/www/api/Messages.java')
-rw-r--r--src/main/java/com/juick/www/api/Messages.java217
1 files changed, 217 insertions, 0 deletions
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 <http://www.gnu.org/licenses/>.
+ */
+
+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<List<Message>> NOT_FOUND = ResponseEntity
+ .status(HttpStatus.NOT_FOUND)
+ .body(Collections.emptyList());
+
+ private static final ResponseEntity<List<Message>> 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<List<Message>> getHome(
+ @Visitor User visitor,
+ @RequestParam(defaultValue = "0") int before_mid) {
+ if (!visitor.isAnonymous()) {
+ int vuid = visitor.getUid();
+ List<Integer> mids = messagesService.getMyFeed(vuid, before_mid, true);
+ List<Message> 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<List<Message>> 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<Integer> 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<Message> 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<Message> getDiscussions(
+ @Visitor User visitor,
+ @RequestParam(required = false, defaultValue = "0") Long to) {
+ List<Message> 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<List<Message>> getThread(
+ @Visitor User visitor,
+ @RequestParam(defaultValue = "0") int mid) {
+ Optional<Message> 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<Message> 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();
+ }
+}