/*
* Copyright (C) 2008-2017, 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.Tag;
import com.juick.formatters.PlainTextFormatter;
import com.juick.server.util.HttpForbiddenException;
import com.juick.server.util.HttpNotFoundException;
import com.juick.server.util.UserUtils;
import com.juick.service.CrosspostService;
import com.juick.service.MessagesService;
import com.juick.service.UserService;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.text.StringEscapeUtils;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import javax.inject.Inject;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
*
* @author Ugnich Anton
*/
@Controller
public class UserThread {
@Inject
private MessagesService messagesService;
@Inject
private UserService userService;
@Inject
private CrosspostService crosspostService;
@GetMapping("/{uname}/{mid}")
protected String threadAction(ModelMap model,
@PathVariable String uname,
@PathVariable int mid,
@RequestParam(required = false, value = "view") String paramView) throws IOException {
com.juick.User visitor = UserUtils.getCurrentUser();
if (!messagesService.canViewThread(mid, visitor.getUid())) {
throw new HttpForbiddenException();
}
com.juick.Message msg = messagesService.getMessage(mid);
if (msg == null || msg.getUser().isBanned()) {
throw new HttpNotFoundException();
}
com.juick.User user = userService.getUserByName(uname);
if (user.getUid() == 0 || !msg.getUser().equals(user)) {
return String.format("redirect:/%s/%d", msg.getUser().getName(), mid);
}
msg.VisitorCanComment = visitor.getUid() > 0;
if (visitor.getUid() > 0) {
msg.VisitorCanComment = visitor.getUid() == msg.getUser().getUid()
|| !userService.isInBL(msg.getUser().getUid(), visitor.getUid());
}
model.addAttribute("msg", msg);
boolean listview = false;
if (paramView != null) {
if (paramView.equals("list")) {
listview = true;
if (visitor.getUid() > 0) {
userService.setUserOptionInt(visitor.getUid(), "repliesview", 1);
}
} else if (paramView.equals("tree") && visitor.getUid() > 0) {
userService.setUserOptionInt(visitor.getUid(), "repliesview", 0);
}
} else if (visitor.getUid() > 0 && userService.getUserOptionInt(visitor.getUid(), "repliesview", 0) == 1) {
listview = true;
}
model.addAttribute("listview", listview);
String title = msg.getUser().getName() + ": " + msg.getTagsString();
model.addAttribute("title", title);
model.addAttribute("visitor", visitor);
String headers = "";
String pageUrl = "https://juick.com/" + msg.getUser().getName() + "/" + msg.getMid();
if (paramView != null) {
headers += "";
}
if (msg.Hidden) {
headers += "";
}
String cardType = StringUtils.isNotEmpty(msg.getAttachmentType()) ? "summary_large_image" : "summary";
String msgImage = StringUtils.isNotEmpty(msg.getAttachmentType()) ? msg.getPhotoURLs().getMedium()
: "https://i.juick.com/a/" + msg.getUser().getUid() + ".png";
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("contentStyle", "margin-left: 0; width: 100%");
model.addAttribute("isModerator", visitor.getUid() == 3694);
model.addAttribute("visitorSubscribed", messagesService.isSubscribed(visitor.getUid(), msg.getMid()));
model.addAttribute("visitorInBL", userService.isInBL(msg.getUser().getUid(), visitor.getUid()));
model.addAttribute("recomm", messagesService.getMessageRecommendations(msg.getMid()));
List replies = messagesService.getReplies(msg.getMid());
List blUIDs = new ArrayList<>();
for (int i = 0; i < replies.size(); i++) {
com.juick.Message reply = replies.get(i);
if (reply.getUser().getUid() != msg.getUser().getUid()
&& !blUIDs.contains(reply.getUser().getUid())) {
blUIDs.add(reply.getUser().getUid());
}
if (reply.getReplyto() > 0) {
boolean added = false;
for (int n = 0; n < replies.size(); n++) {
if (replies.get(n).getRid() == reply.getReplyto()) {
replies.get(n).childs.add(reply);
added = true;
break;
}
}
if (!added) {
reply.setReplyto(0);
}
}
if (visitor.getUid() > 0 && msg.getUser().getUid() == visitor.getUid()) {
reply.VisitorCanComment = true;
} else if (visitor.getUid() > 0 && msg.VisitorCanComment) {
List blUIDs2 = userService.checkBL(visitor.getUid(), blUIDs);
reply.VisitorCanComment = reply.getUser().getUid() == visitor.getUid()
|| !blUIDs2.contains(reply.getUser().getUid());
} else {
reply.VisitorCanComment = false;
}
}
boolean foldable = false;
if (replies.size() > 10) {
for (int i = 0; i < replies.size() - 1; i++) {
if (replies.get(i).getChildsCount() > 1) {
foldable = true;
break;
}
}
}
model.addAttribute("replies", replies);
model.addAttribute("foldable", foldable);
return "views/thread";
}
// when message id is not fit to int
@ExceptionHandler(NumberFormatException.class)
public ResponseEntity notFoundAction() {
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
}