added entry edit
This commit is contained in:
parent
2a646b0ece
commit
dcdb140f67
2
pom.xml
2
pom.xml
@ -10,7 +10,7 @@
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<java.version>11</java.version>
|
||||
<revision>1.0.0</revision>
|
||||
<revision>1.0.1</revision>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
|
@ -99,4 +99,17 @@ public class BookmarksManager {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the entry.
|
||||
*
|
||||
* @param entryId the entry id
|
||||
*/
|
||||
public void removeEntry(Long entryId) {
|
||||
for (Bookmarks bookmarks : bookmarksRepository
|
||||
.findAll(qBookmarks.entries.contains(entryId))) {
|
||||
bookmarks.getEntries().remove(entryId);
|
||||
bookmarksRepository.save(bookmarks);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -283,6 +283,7 @@ public class CommentManager {
|
||||
}
|
||||
|
||||
voteManager.deleteByTarget(comment.getId(), Types.comment);
|
||||
flagManager.deleteByTarget(comment.getId(), Types.comment);
|
||||
|
||||
commentRepository.delete(comment);
|
||||
}
|
||||
|
@ -3,9 +3,13 @@
|
||||
*/
|
||||
package de.bstly.board.businesslogic;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
|
||||
import javax.persistence.EntityManager;
|
||||
import javax.persistence.Query;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
@ -21,11 +25,10 @@ import com.querydsl.jpa.impl.JPAQueryFactory;
|
||||
|
||||
import de.bstly.board.model.Bookmarks;
|
||||
import de.bstly.board.model.Entry;
|
||||
import de.bstly.board.model.EntryStatus;
|
||||
import de.bstly.board.model.FlaggedStatus;
|
||||
import de.bstly.board.model.QEntry;
|
||||
import de.bstly.board.model.QFlag;
|
||||
import de.bstly.board.model.QVote;
|
||||
import de.bstly.board.model.RankedEntry;
|
||||
import de.bstly.board.model.Types;
|
||||
import de.bstly.board.model.VoteType;
|
||||
import de.bstly.board.repository.EntryRepository;
|
||||
@ -53,61 +56,195 @@ public class EntryManager {
|
||||
private FlagManager flagManager;
|
||||
@Autowired
|
||||
private JPAQueryFactory jpaQueryFactory;
|
||||
@Autowired
|
||||
private EntityManager em;
|
||||
|
||||
private QEntry qEntry = QEntry.entry;
|
||||
private QVote qVote = QVote.vote;
|
||||
private QFlag qFlag = QFlag.flag;
|
||||
|
||||
static final String UPVOTES_QUERY = "SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 1 GROUP BY upvote.target";
|
||||
|
||||
static final String DOWNVOTES_QUERY = "SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 AND downvote.target_type = 1 GROUP BY downvote.target";
|
||||
|
||||
static final String COMMENTS_QUERY = "SELECT comment.target,MAX(comment.created) as last,COUNT(comment.id) AS count FROM comments as comment WHERE comment.flagged_status = :flag GROUP BY comment.target";
|
||||
|
||||
static final String RANK_CALCULATION_QUERY = "SELECT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / IF(:gravity > 0, POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity), 1) AS ranking FROM entries AS entry LEFT JOIN ("
|
||||
+ UPVOTES_QUERY
|
||||
+ ") AS upvote ON upvote.target = entry.id LEFT JOIN ("
|
||||
+ DOWNVOTES_QUERY
|
||||
+ ") AS downvote ON downvote.target = entry.id WHERE %s ORDER BY ranking DESC, entry.created DESC";
|
||||
|
||||
static final String DATE_QUERY = "SELECT entry.*FROM entries AS entry WHERE %s ORDER BY entry.created DESC";
|
||||
|
||||
static final String COMMENT_CALCULATION_QUERY = "SELECT entry.*, IFNULL(comment.count,0) as comments, IFNULL(comment.count,0) / IF(:gravity > 0, POW(TIMESTAMPDIFF(HOUR, comment.last, :before)+2,:gravity), 1) AS ranking FROM entries AS entry LEFT JOIN ("
|
||||
+ COMMENTS_QUERY
|
||||
+ ") AS comment ON comment.target = entry.id WHERE %s ORDER BY ranking DESC, entry.created DESC";
|
||||
|
||||
static final String LAST_COMMENT_QUERY = "SELECT entry.* FROM entries AS entry LEFT JOIN ("
|
||||
+ COMMENTS_QUERY
|
||||
+ ") AS comment ON comment.target = entry.id WHERE %s ORDER BY comment.last DESC, entry.created DESC";
|
||||
|
||||
static final String COUNT_QUERY = "SELECT count(entry.id) FROM entries as entry WHERE %s";
|
||||
|
||||
/**
|
||||
* Fetch by ranking.
|
||||
*
|
||||
* @param username the username
|
||||
* @param date the date
|
||||
* @param flaggedStatus the flagged status
|
||||
* @param gravity the gravity
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
public Page<RankedEntry> fetchByRanking(Instant date, double gravity, int page, int size) {
|
||||
return entryRepository.findAllByRanking(date, gravity, PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch by comments.
|
||||
*
|
||||
* @param date the date
|
||||
* @param gravity the gravity
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
public Page<RankedEntry> fetchByComments(Instant date, double gravity, int page, int size) {
|
||||
return entryRepository.findAllByComments(date, gravity, PageRequest.of(page, size));
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch by last comment.
|
||||
*
|
||||
* @param date the date
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
public Page<Entry> fetchByLastComment(Instant date, int page, int size) {
|
||||
return entryRepository.findAllByLastComment(date, PageRequest.of(page, size));
|
||||
public Page<Entry> fetchByRanking(String username, Instant date, FlaggedStatus flaggedStatus,
|
||||
double gravity, int page, int size) {
|
||||
Query query = createEntryQuery(RANK_CALCULATION_QUERY, username, date, flaggedStatus);
|
||||
query.setParameter("gravity", gravity);
|
||||
query.setFirstResult((page) * size);
|
||||
query.setMaxResults(size);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Entry> list = query.getResultList();
|
||||
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus);
|
||||
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
|
||||
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch by date.
|
||||
*
|
||||
* @param username the username
|
||||
* @param date the date
|
||||
* @param flaggedStatus the flagged status
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
public Page<Entry> fetchByDate(Instant date, int page, int size) {
|
||||
return entryRepository.findAll(
|
||||
qEntry.created.before(date).and(qEntry.entryStatus.eq(EntryStatus.NORMAL)),
|
||||
PageRequest.of(page, size, Sort.by(Order.desc("created"))));
|
||||
public Page<Entry> fetchByDate(String username, Instant date, FlaggedStatus flaggedStatus,
|
||||
int page, int size) {
|
||||
Query query = createEntryQuery(DATE_QUERY, username, date, flaggedStatus);
|
||||
query.setFirstResult((page) * size);
|
||||
query.setMaxResults(size);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Entry> list = query.getResultList();
|
||||
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus);
|
||||
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
|
||||
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch by comments.
|
||||
*
|
||||
* @param username the username
|
||||
* @param date the date
|
||||
* @param flaggedStatus the flagged status
|
||||
* @param gravity the gravity
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
public Page<Entry> fetchByComments(String username, Instant date, FlaggedStatus flaggedStatus,
|
||||
double gravity, int page, int size) {
|
||||
Query query = createEntryQuery(COMMENT_CALCULATION_QUERY, username, date, flaggedStatus);
|
||||
query.setParameter("gravity", gravity);
|
||||
query.setFirstResult((page) * size);
|
||||
query.setMaxResults(size);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Entry> list = query.getResultList();
|
||||
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus);
|
||||
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
|
||||
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch by last comment.
|
||||
*
|
||||
* @param username the username
|
||||
* @param date the date
|
||||
* @param flaggedStatus the flagged status
|
||||
* @param page the page
|
||||
* @param size the size
|
||||
* @return the page
|
||||
*/
|
||||
public Page<Entry> fetchByLastComment(String username, Instant date,
|
||||
FlaggedStatus flaggedStatus, int page, int size) {
|
||||
Query query = createEntryQuery(LAST_COMMENT_QUERY, username, date, flaggedStatus);
|
||||
query.setFirstResult((page) * size);
|
||||
query.setMaxResults(size);
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Entry> list = query.getResultList();
|
||||
Query queryTotal = createCountQuery(COUNT_QUERY, username, date, flaggedStatus);
|
||||
long countResult = ((BigInteger) queryTotal.getSingleResult()).longValue();
|
||||
return new PageImpl<Entry>(list, PageRequest.of(page, size), countResult);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the entry query.
|
||||
*
|
||||
* @param rawQuery the raw query
|
||||
* @param username the username
|
||||
* @param date the date
|
||||
* @param flaggedStatus the flagged status
|
||||
* @return the query
|
||||
*/
|
||||
protected Query createEntryQuery(String rawQuery, String username, Instant date,
|
||||
FlaggedStatus flaggedStatus) {
|
||||
String filterString = "";
|
||||
|
||||
boolean author = false;
|
||||
if (date != null) {
|
||||
filterString = "entry.created < :before";
|
||||
} else {
|
||||
date = Instant.now();
|
||||
author = true;
|
||||
filterString = "(entry.created < :before OR entry.author = :author)";
|
||||
}
|
||||
|
||||
filterString += " AND entry.flagged_status = :flag";
|
||||
|
||||
Query query = em.createNativeQuery(String.format(rawQuery, filterString), Entry.class);
|
||||
query.setParameter("before", date);
|
||||
if (author) {
|
||||
query.setParameter("author", username);
|
||||
}
|
||||
query.setParameter("flag", flaggedStatus.toString());
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates the count query.
|
||||
*
|
||||
* @param rawQuery the raw query
|
||||
* @param username the username
|
||||
* @param date the date
|
||||
* @param flaggedStatus the flagged status
|
||||
* @return the query
|
||||
*/
|
||||
protected Query createCountQuery(String rawQuery, String username, Instant date,
|
||||
FlaggedStatus flaggedStatus) {
|
||||
String filterString = "";
|
||||
|
||||
boolean author = false;
|
||||
if (date != null) {
|
||||
filterString = "entry.created < :before";
|
||||
} else {
|
||||
date = Instant.now();
|
||||
author = true;
|
||||
filterString = "(entry.created < :before OR entry.author = :author)";
|
||||
}
|
||||
|
||||
filterString += " AND entry.flagged_status = :flag";
|
||||
|
||||
Query query = em.createNativeQuery(String.format(rawQuery, filterString));
|
||||
query.setParameter("before", date);
|
||||
if (author) {
|
||||
query.setParameter("author", username);
|
||||
}
|
||||
query.setParameter("flag", flaggedStatus.toString());
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -295,6 +432,8 @@ public class EntryManager {
|
||||
public void delete(Entry entry) {
|
||||
commentManager.deleteByTarget(entry.getId());
|
||||
voteManager.deleteByTarget(entry.getId(), Types.entry);
|
||||
bookmarksManager.removeEntry(entry.getId());
|
||||
flagManager.deleteByTarget(entry.getId(), Types.entry);
|
||||
entryRepository.delete(entry);
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,8 @@ public class SettingsManager {
|
||||
private double GRAVITY;
|
||||
@Value("${bstly.board.size:30}")
|
||||
private int SIZE;
|
||||
@Value("${bstly.board.entry.changePeriod:1}")
|
||||
private long ENTRY_CHANGE_PERIDO;
|
||||
@Value("${bstly.board.comment.changePeriod:1}")
|
||||
private long COMMENT_CHANGE_PERIDO;
|
||||
@Value("${bstly.board.unvoteThresh:10}")
|
||||
@ -41,6 +43,15 @@ public class SettingsManager {
|
||||
return SIZE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entry delay.
|
||||
*
|
||||
* @return the entry delay
|
||||
*/
|
||||
public long getEntryDelay() {
|
||||
return ENTRY_CHANGE_PERIDO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the comment delay.
|
||||
*
|
||||
|
@ -107,6 +107,24 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
|
||||
/*
|
||||
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.security.core.userdetails.UserDetailsService#loadUserByUsername(java.lang.String)
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.security.core.userdetails.UserDetailsService#
|
||||
* loadUserByUsername(java.lang.String)
|
||||
@ -188,6 +206,24 @@ public class UserManager implements UserDetailsService, SmartInitializingSinglet
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#afterSingletonsInstantiated()
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.beans.factory.SmartInitializingSingleton#
|
||||
* afterSingletonsInstantiated()
|
||||
|
@ -18,7 +18,7 @@ import de.bstly.board.security.LocalUserDetails;
|
||||
public class BaseController {
|
||||
|
||||
@Autowired
|
||||
private UserManager localUserManager;
|
||||
private UserManager userManager;
|
||||
@Autowired
|
||||
private SettingsManager settingsManager;
|
||||
|
||||
@ -62,7 +62,7 @@ public class BaseController {
|
||||
protected int getPageSize() {
|
||||
String username = getCurrentUsername();
|
||||
if (username != null) {
|
||||
LocalUser localUser = localUserManager.getByUsername(username);
|
||||
LocalUser localUser = userManager.getByUsername(username);
|
||||
if (localUser.getSettings() != null
|
||||
&& localUser.getSettings().containsKey("pageSize")) {
|
||||
try {
|
||||
@ -83,7 +83,7 @@ public class BaseController {
|
||||
protected double getGravity() {
|
||||
String username = getCurrentUsername();
|
||||
if (username != null) {
|
||||
LocalUser localUser = localUserManager.getByUsername(username);
|
||||
LocalUser localUser = userManager.getByUsername(username);
|
||||
if (localUser.getSettings() != null && localUser.getSettings().containsKey("gravity")) {
|
||||
try {
|
||||
double gravity = Double.parseDouble(localUser.getSettings().get("gravity"));
|
||||
@ -103,6 +103,36 @@ public class BaseController {
|
||||
return settingsManager.getGravity();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the entry delay.
|
||||
*
|
||||
* @return the entry delay
|
||||
*/
|
||||
protected long getEntryDelay() {
|
||||
String username = getCurrentUsername();
|
||||
if (username != null) {
|
||||
LocalUser localUser = userManager.getByUsername(username);
|
||||
if (localUser.getSettings() != null
|
||||
&& localUser.getSettings().containsKey("entryDelay")) {
|
||||
try {
|
||||
long entryDelay = Long.parseLong(localUser.getSettings().get("entryDelay"));
|
||||
|
||||
if (entryDelay < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (entryDelay > 15) {
|
||||
return 15;
|
||||
}
|
||||
|
||||
return entryDelay;
|
||||
} catch (Exception e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
return settingsManager.getEntryDelay();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the comment delay.
|
||||
*
|
||||
@ -111,7 +141,7 @@ public class BaseController {
|
||||
protected long getCommentDelay() {
|
||||
String username = getCurrentUsername();
|
||||
if (username != null) {
|
||||
LocalUser localUser = localUserManager.getByUsername(username);
|
||||
LocalUser localUser = userManager.getByUsername(username);
|
||||
if (localUser.getSettings() != null
|
||||
&& localUser.getSettings().containsKey("commentDelay")) {
|
||||
try {
|
||||
|
@ -8,17 +8,17 @@ import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.net.URLDecoder;
|
||||
import java.time.Instant;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Scanner;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.PageImpl;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PatchMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
@ -38,7 +38,6 @@ import de.bstly.board.controller.validation.EntryValidator;
|
||||
import de.bstly.board.model.Entry;
|
||||
import de.bstly.board.model.EntryStatus;
|
||||
import de.bstly.board.model.FlaggedStatus;
|
||||
import de.bstly.board.model.RankedEntry;
|
||||
import de.bstly.board.model.Types;
|
||||
import de.bstly.board.model.Vote;
|
||||
import de.bstly.board.model.VoteType;
|
||||
@ -91,21 +90,15 @@ public class EntryController extends BaseController {
|
||||
gravityParameter = Optional.of(2.0);
|
||||
}
|
||||
|
||||
Page<RankedEntry> entries = entryManager.fetchByRanking(dateParameter.orElse(Instant.now()),
|
||||
Page<Entry> entries = entryManager.fetchByRanking(getCurrentUsername(),
|
||||
dateParameter.orElse(null), FlaggedStatus.NORMAL,
|
||||
gravityParameter.orElse(getGravity()), pageParameter.orElse(0),
|
||||
sizeParameter.orElse(settingsManager.getPageSize()));
|
||||
|
||||
Page<Entry> transformed = new PageImpl<Entry>(
|
||||
entries.getContent().stream().map(rankedEntry -> {
|
||||
Entry entry = Entry.fromRankedEntry(rankedEntry);
|
||||
entry.getMetadata().put("points", rankedEntry.getPoints());
|
||||
return entry;
|
||||
}).collect(Collectors.toList()), entries.getPageable(), entries.getTotalElements());
|
||||
|
||||
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
|
||||
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
|
||||
transformed.getContent(), ignore);
|
||||
return transformed;
|
||||
entries.getContent(), ignore);
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -132,8 +125,9 @@ public class EntryController extends BaseController {
|
||||
dateParameter = Optional.of(Instant.now());
|
||||
}
|
||||
|
||||
Page<Entry> entries = entryManager.fetchByDate(dateParameter.orElse(Instant.now()),
|
||||
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()));
|
||||
Page<Entry> entries = entryManager.fetchByDate(getCurrentUsername(),
|
||||
dateParameter.orElse(null), FlaggedStatus.NORMAL, pageParameter.orElse(0),
|
||||
sizeParameter.orElse(settingsManager.getPageSize()));
|
||||
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
|
||||
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
|
||||
entries.getContent(), ignore);
|
||||
@ -166,19 +160,15 @@ public class EntryController extends BaseController {
|
||||
dateParameter = Optional.of(Instant.now());
|
||||
}
|
||||
|
||||
Page<RankedEntry> entries = entryManager.fetchByComments(
|
||||
dateParameter.orElse(Instant.now()), gravityParameter.orElse(getGravity()),
|
||||
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()));
|
||||
|
||||
Page<Entry> transformed = new PageImpl<Entry>(
|
||||
entries.getContent().stream().map(rankedEntry -> Entry.fromRankedEntry(rankedEntry))
|
||||
.collect(Collectors.toList()),
|
||||
entries.getPageable(), entries.getTotalElements());
|
||||
Page<Entry> entries = entryManager.fetchByComments(getCurrentUsername(),
|
||||
dateParameter.orElse(null), FlaggedStatus.NORMAL,
|
||||
gravityParameter.orElse(getGravity()), pageParameter.orElse(0),
|
||||
sizeParameter.orElse(settingsManager.getPageSize()));
|
||||
|
||||
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
|
||||
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
|
||||
transformed.getContent(), ignore);
|
||||
return transformed;
|
||||
entries.getContent(), ignore);
|
||||
return entries;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,8 +195,9 @@ public class EntryController extends BaseController {
|
||||
dateParameter = Optional.of(Instant.now());
|
||||
}
|
||||
|
||||
Page<Entry> entries = entryManager.fetchByLastComment(dateParameter.orElse(Instant.now()),
|
||||
pageParameter.orElse(0), sizeParameter.orElse(settingsManager.getPageSize()));
|
||||
Page<Entry> entries = entryManager.fetchByLastComment(getCurrentUsername(),
|
||||
dateParameter.orElse(null), FlaggedStatus.NORMAL, pageParameter.orElse(0),
|
||||
sizeParameter.orElse(settingsManager.getPageSize()));
|
||||
|
||||
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
|
||||
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
|
||||
@ -294,7 +285,7 @@ public class EntryController extends BaseController {
|
||||
HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
entry.setCreated(Instant.now());
|
||||
entry.setCreated(Instant.now().plus(getEntryDelay(), ChronoUnit.MINUTES));
|
||||
entry.setAuthor(getCurrentUsername());
|
||||
entry.setEntryStatus(EntryStatus.NORMAL);
|
||||
entry.setFlaggedStatus(FlaggedStatus.NORMAL);
|
||||
@ -316,6 +307,57 @@ public class EntryController extends BaseController {
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update entry.
|
||||
*
|
||||
* @param entry the entry
|
||||
* @param ignoreParameter the ignore parameter
|
||||
* @return the entry
|
||||
*/
|
||||
@PreAuthorize("isAuthenticated()")
|
||||
@PatchMapping
|
||||
public Entry updateEntry(@RequestBody Entry entry,
|
||||
@RequestParam("ignore") Optional<List<String>> ignoreParameter) {
|
||||
Entry orgEnry = entryManager.get(entry.getId());
|
||||
if (orgEnry == null || !orgEnry.getAuthor().equals(getCurrentUsername()) || orgEnry
|
||||
.getCreated().plus(getEntryDelay(), ChronoUnit.MINUTES).isBefore(Instant.now())) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
RequestBodyErrors bindingResult = new RequestBodyErrors(entry);
|
||||
entryValidator.validate(entry, bindingResult);
|
||||
|
||||
if (bindingResult.hasErrors()) {
|
||||
throw new EntityResponseStatusException(bindingResult.getAllErrors(),
|
||||
HttpStatus.UNPROCESSABLE_ENTITY);
|
||||
}
|
||||
|
||||
orgEnry.setUrl(entry.getUrl());
|
||||
orgEnry.setTitle(entry.getTitle().trim());
|
||||
orgEnry.setText(entry.getText().trim());
|
||||
orgEnry = entryManager.save(orgEnry);
|
||||
|
||||
List<String> ignore = ignoreParameter.orElse(Lists.newArrayList());
|
||||
entryManager.applyMetadata(getCurrentUsername(), userManager.getKarma(getCurrentUsername()),
|
||||
entry, ignore);
|
||||
return entry;
|
||||
}
|
||||
|
||||
/**
|
||||
* Detele entry.
|
||||
*
|
||||
* @param id the id
|
||||
*/
|
||||
public void deteleEntry(@PathVariable("id") Long id) {
|
||||
Entry orgEntry = entryManager.get(id);
|
||||
if (orgEntry == null || !orgEntry.getAuthor().equals(getCurrentUsername()) || orgEntry
|
||||
.getCreated().plus(getEntryDelay(), ChronoUnit.MINUTES).isBefore(Instant.now())) {
|
||||
throw new EntityResponseStatusException(HttpStatus.FORBIDDEN);
|
||||
}
|
||||
|
||||
entryManager.delete(orgEntry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title.
|
||||
*
|
||||
|
@ -34,9 +34,11 @@ public class SettingsController extends BaseController {
|
||||
Map<String, Object> settings = Maps.newHashMap();
|
||||
settings.put("gravity", getGravity());
|
||||
settings.put("pageSize", getPageSize());
|
||||
settings.put("entryDelay", getEntryDelay());
|
||||
settings.put("commentDelay", getCommentDelay());
|
||||
settings.put("defaultGravity", settingsManager.getGravity());
|
||||
settings.put("defaultPageSize", settingsManager.getPageSize());
|
||||
settings.put("defaultEntryDelay", settingsManager.getEntryDelay());
|
||||
settings.put("defaultCommentDelay", settingsManager.getCommentDelay());
|
||||
return settings;
|
||||
}
|
||||
|
@ -57,6 +57,8 @@ public class Entry {
|
||||
@Transient
|
||||
private Double ranking;
|
||||
@Transient
|
||||
private Long points;
|
||||
@Transient
|
||||
private Map<String, Object> metadata;
|
||||
|
||||
/**
|
||||
@ -239,6 +241,24 @@ public class Entry {
|
||||
this.ranking = ranking;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the points.
|
||||
*
|
||||
* @return the points
|
||||
*/
|
||||
public Long getPoints() {
|
||||
return points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the points.
|
||||
*
|
||||
* @param points the new points
|
||||
*/
|
||||
public void setPoints(Long points) {
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the metadata.
|
||||
*
|
||||
@ -260,23 +280,4 @@ public class Entry {
|
||||
this.metadata = metadata;
|
||||
}
|
||||
|
||||
/**
|
||||
* From ranked entry.
|
||||
*
|
||||
* @param rankedEntry the ranked entry
|
||||
* @return the entry
|
||||
*/
|
||||
public static Entry fromRankedEntry(RankedEntry rankedEntry) {
|
||||
Entry entry = new Entry();
|
||||
entry.setId(rankedEntry.getId());
|
||||
entry.setAuthor(rankedEntry.getAuthor());
|
||||
entry.setCreated(rankedEntry.getCreated());
|
||||
entry.setEntryType(rankedEntry.getEntry_Type());
|
||||
entry.setUrl(rankedEntry.getUrl());
|
||||
entry.setTitle(rankedEntry.getTitle());
|
||||
entry.setText(rankedEntry.getText());
|
||||
entry.setRanking(rankedEntry.getRanking());
|
||||
return entry;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,76 +0,0 @@
|
||||
/**
|
||||
*
|
||||
*/
|
||||
package de.bstly.board.model;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
|
||||
/**
|
||||
* The Interface RankedEntry.
|
||||
*/
|
||||
public interface RankedEntry {
|
||||
|
||||
/**
|
||||
* Gets the id.
|
||||
*
|
||||
* @return the id
|
||||
*/
|
||||
Long getId();
|
||||
|
||||
/**
|
||||
* Gets the author.
|
||||
*
|
||||
* @return the author
|
||||
*/
|
||||
String getAuthor();
|
||||
|
||||
/**
|
||||
* Gets the created.
|
||||
*
|
||||
* @return the created
|
||||
*/
|
||||
Instant getCreated();
|
||||
|
||||
/**
|
||||
* Gets the entry type.
|
||||
*
|
||||
* @return the entry type
|
||||
*/
|
||||
EntryType getEntry_Type();
|
||||
|
||||
/**
|
||||
* Gets the url.
|
||||
*
|
||||
* @return the url
|
||||
*/
|
||||
String getUrl();
|
||||
|
||||
/**
|
||||
* Gets the title.
|
||||
*
|
||||
* @return the title
|
||||
*/
|
||||
String getTitle();
|
||||
|
||||
/**
|
||||
* Gets the text.
|
||||
*
|
||||
* @return the text
|
||||
*/
|
||||
String getText();
|
||||
|
||||
/**
|
||||
* Gets the ranking.
|
||||
*
|
||||
* @return the ranking
|
||||
*/
|
||||
Double getRanking();
|
||||
|
||||
/**
|
||||
* Gets the points.
|
||||
*
|
||||
* @return the points
|
||||
*/
|
||||
Long getPoints();
|
||||
}
|
@ -3,18 +3,11 @@
|
||||
*/
|
||||
package de.bstly.board.repository;
|
||||
|
||||
import java.time.Instant;
|
||||
|
||||
import org.springframework.data.domain.Page;
|
||||
import org.springframework.data.domain.Pageable;
|
||||
import org.springframework.data.jpa.repository.JpaRepository;
|
||||
import org.springframework.data.jpa.repository.Query;
|
||||
import org.springframework.data.querydsl.QuerydslPredicateExecutor;
|
||||
import org.springframework.data.repository.query.Param;
|
||||
import org.springframework.stereotype.Repository;
|
||||
|
||||
import de.bstly.board.model.Entry;
|
||||
import de.bstly.board.model.RankedEntry;
|
||||
|
||||
/**
|
||||
* The Interface EntryRepository.
|
||||
@ -23,60 +16,4 @@ import de.bstly.board.model.RankedEntry;
|
||||
public interface EntryRepository
|
||||
extends JpaRepository<Entry, Long>, QuerydslPredicateExecutor<Entry> {
|
||||
|
||||
static final String UPVOTES_QUERY = "SELECT upvote.target,COUNT(upvote.id) AS count FROM votes as upvote WHERE upvote.type = 0 AND upvote.target_type = 1 GROUP BY upvote.target";
|
||||
|
||||
static final String DOWNVOTES_QUERY = "SELECT downvote.target,COUNT(downvote.id) AS count FROM votes as downvote WHERE downvote.type = 1 AND downvote.target_type = 1 GROUP BY downvote.target";
|
||||
|
||||
static final String COMMENTS_QUERY = "SELECT comment.target,MAX(comment.created) as last,COUNT(comment.id) AS count FROM comments as comment WHERE comment.flagged_status = 'NORMAL' GROUP BY comment.target";
|
||||
|
||||
static final String RANK_CALCULATION_QUERY = "SELECT entry.*, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) as points, (IFNULL(upvote.count,0) - IFNULL(downvote.count,0)) / IF(:gravity > 0, POW(TIMESTAMPDIFF(HOUR, entry.created, :before)+2,:gravity), 1) AS ranking FROM entries AS entry LEFT JOIN ("
|
||||
+ UPVOTES_QUERY
|
||||
+ ") AS upvote ON upvote.target = entry.id LEFT JOIN ("
|
||||
+ DOWNVOTES_QUERY
|
||||
+ ") AS downvote ON downvote.target = entry.id WHERE entry.created < :before AND entry.flagged_status = 'NORMAL' ORDER BY ranking DESC, entry.created DESC";
|
||||
|
||||
static final String COMMENT_CALCULATION_QUERY = "SELECT entry.*, IFNULL(comment.count,0) as comments, IFNULL(comment.count,0) / IF(:gravity > 0, POW(TIMESTAMPDIFF(HOUR, comment.last, :before)+2,:gravity), 1) AS ranking FROM entries AS entry LEFT JOIN ("
|
||||
+ COMMENTS_QUERY
|
||||
+ ") AS comment ON comment.target = entry.id WHERE entry.created < :before AND entry.flagged_status = 'NORMAL' ORDER BY ranking DESC, entry.created DESC";
|
||||
|
||||
static final String LAST_COMMENT_QUERY = "SELECT entry.* FROM entries AS entry LEFT JOIN ("
|
||||
+ COMMENTS_QUERY
|
||||
+ ") AS comment ON comment.target = entry.id WHERE entry.created < :before AND entry.flagged_status = 'NORMAL' ORDER BY comment.last DESC, entry.created DESC";
|
||||
|
||||
static final String COUNT_QUERY = "SELECT count(*) FROM entries as entry WHERE entry.created < :before AND entry.flagged_status = 'NORMAL'";
|
||||
|
||||
/**
|
||||
* Find all by ranking.
|
||||
*
|
||||
* @param before the before
|
||||
* @param gravity the gravity
|
||||
* @param pageable the pageable
|
||||
* @return the page
|
||||
*/
|
||||
@Query(value = RANK_CALCULATION_QUERY, countQuery = COUNT_QUERY, nativeQuery = true)
|
||||
Page<RankedEntry> findAllByRanking(@Param("before") Instant before,
|
||||
@Param("gravity") double gravity, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Find all by comments.
|
||||
*
|
||||
* @param before the before
|
||||
* @param gravity the gravity
|
||||
* @param pageable the pageable
|
||||
* @return the page
|
||||
*/
|
||||
@Query(value = COMMENT_CALCULATION_QUERY, countQuery = COUNT_QUERY, nativeQuery = true)
|
||||
Page<RankedEntry> findAllByComments(@Param("before") Instant before,
|
||||
@Param("gravity") double gravity, Pageable pageable);
|
||||
|
||||
/**
|
||||
* Find all by last comment.
|
||||
*
|
||||
* @param before the before
|
||||
* @param pageable the pageable
|
||||
* @return the page
|
||||
*/
|
||||
@Query(value = LAST_COMMENT_QUERY, countQuery = COUNT_QUERY, nativeQuery = true)
|
||||
Page<Entry> findAllByLastComment(@Param("before") Instant before, Pageable pageable);
|
||||
|
||||
}
|
||||
|
@ -50,6 +50,9 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
@Value("${loginTargetUrl:/}")
|
||||
private String loginTargetUrl;
|
||||
|
||||
/*
|
||||
* @see org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter#configure(org.springframework.security.config.annotation.web.builders.HttpSecurity)
|
||||
*/
|
||||
/*
|
||||
* @see org.springframework.security.config.annotation.web.configuration.
|
||||
* WebSecurityConfigurerAdapter#configure(org.springframework.security.config.
|
||||
@ -126,6 +129,11 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter {
|
||||
return rememberMeServices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cors configuration source.
|
||||
*
|
||||
* @return the cors configuration source
|
||||
*/
|
||||
@Bean
|
||||
public CorsConfigurationSource corsConfigurationSource() {
|
||||
CorsConfiguration configuration = new CorsConfiguration();
|
||||
|
Loading…
Reference in New Issue
Block a user