package io.kaif.web.api; import static java.util.stream.Collectors.*; import java.util.List; import javax.validation.Valid; import javax.validation.constraints.NotNull; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.dao.DuplicateKeyException; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import io.kaif.flake.FlakeId; import io.kaif.model.account.AccountAccessToken; import io.kaif.model.vote.ArticleVoter; import io.kaif.model.vote.ArticleVoterDto; import io.kaif.model.vote.DebateVoter; import io.kaif.model.vote.DebateVoterDto; import io.kaif.model.vote.VoteState; import io.kaif.service.VoteService; @RestController @RequestMapping("/api/vote") public class VoteResource { static class VoteArticle { @NotNull public FlakeId articleId; @NotNull public Long previousCount; @NotNull public VoteState newState; @NotNull public VoteState previousState; } static class VoteDebate { @NotNull public FlakeId debateId; @NotNull public VoteState newState; @NotNull public VoteState previousState; @NotNull public Long previousCount; } @Autowired private VoteService voteService; @RequestMapping(value = "/article", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE }) public void voteArticle(AccountAccessToken token, @Valid @RequestBody VoteArticle request) { ignoreDuplicateVote(() -> // voteService.voteArticle(request.newState, request.articleId, token, request.previousState, request.previousCount)); } private void ignoreDuplicateVote(Runnable runnable) { try { runnable.run(); } catch (DuplicateKeyException ignore) { // user duplicate vote, this mostly happened when user press browser back. // this typically is fine, we safely ignore } } @RequestMapping(value = "/debate", method = RequestMethod.POST, consumes = { MediaType.APPLICATION_JSON_VALUE }) public void voteDebate(AccountAccessToken token, @Valid @RequestBody VoteDebate request) { ignoreDuplicateVote(() -> // voteService.voteDebate(request.newState, request.debateId, token, request.previousState, request.previousCount)); } @RequestMapping(value = "/article-voters", method = RequestMethod.GET) public List<ArticleVoterDto> listArticleVoters(AccountAccessToken token, @RequestParam("articleIds") List<String> articleIds) { List<FlakeId> flakeIds = articleIds.stream().map(FlakeId::fromString).collect(toList()); return voteService.listArticleVoters(token, flakeIds) .stream() .map(ArticleVoter::toDto) .collect(toList()); } @RequestMapping(value = "/debate-voters", method = RequestMethod.GET) public List<DebateVoterDto> lisDebateVoters(AccountAccessToken token, @RequestParam("articleId") FlakeId articleId) { return voteService.listDebateVoters(token, articleId) .stream() .map(DebateVoter::toDto) .collect(toList()); } @RequestMapping(value = "/debate-voters-by-ids", method = RequestMethod.GET) public List<DebateVoterDto> lisDebateVoters(AccountAccessToken token, @RequestParam("debateIds") List<String> debateIds) { List<FlakeId> flakeIds = debateIds.stream().map(FlakeId::fromString).collect(toList()); return voteService.listDebateVotersByIds(token, flakeIds) .stream() .map(DebateVoter::toDto) .collect(toList()); } }