package fr.ippon.tatami.web.rest; import com.yammer.metrics.annotation.Timed; import fr.ippon.tatami.domain.Group; import fr.ippon.tatami.domain.User; import fr.ippon.tatami.domain.status.AbstractStatus; import fr.ippon.tatami.domain.status.StatusDetails; import fr.ippon.tatami.security.AuthenticationService; import fr.ippon.tatami.service.GroupService; import fr.ippon.tatami.service.StatusUpdateService; import fr.ippon.tatami.service.TimelineService; import fr.ippon.tatami.service.dto.StatusDTO; import fr.ippon.tatami.service.exception.ArchivedGroupException; import fr.ippon.tatami.service.exception.ReplyStatusException; import fr.ippon.tatami.web.rest.dto.ActionStatus; import org.apache.commons.lang.StringEscapeUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import twitter4j.StatusUpdate; import javax.inject.Inject; import javax.servlet.http.HttpServletResponse; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.Collection; /** * REST controller for managing status. * * @author Julien Dubois */ @Controller public class TimelineController { private final Logger log = LoggerFactory.getLogger(TimelineController.class); @Inject private TimelineService timelineService; @Inject private StatusUpdateService statusUpdateService; @Inject private GroupService groupService; @Inject private AuthenticationService authenticationService; /** * GET /statuses/details/:id -> returns the details for a status, specified by the id parameter */ @RequestMapping(value = "/rest/statuses/details/{statusId}", method = RequestMethod.GET, produces = "application/json") @ResponseBody public StatusDetails getStatusDetails(@PathVariable("statusId") String statusId) { log.debug("REST request to get status details Id : {}", statusId); return timelineService.getStatusDetails(statusId); } /** * Report a status */ @RequestMapping(value = "/rest/statuses/report/{statusId}", method = RequestMethod.POST) @ResponseBody public void reportStatus(@PathVariable("statusId") String statusId) { log.debug("REST request to report a status details Id : {}", statusId); statusUpdateService.reportStatus(authenticationService.getCurrentUser().getLogin(), statusId); } /** * Report a status */ @RequestMapping(value = "/rest/statuses/report/reportedList", method = RequestMethod.GET, produces = "application/json") @ResponseBody public Collection<StatusDTO> getReportStatuses() { log.debug("REST request to get all reports"); Collection<StatusDTO> reportedStatusList = statusUpdateService.findReportedStatuses(); return reportedStatusList; } @RequestMapping(value = "/rest/statuses/report/{statusId}", method = RequestMethod.PUT) @ResponseBody public void deleteReportedStatus(@PathVariable("statusId") String statusId) { log.debug("REST request to delete a status Id : {}", statusId); statusUpdateService.deleteReportedStatus(statusId); } @RequestMapping(value = "/rest/statuses/report/{statusId}", method = RequestMethod.DELETE) @ResponseBody public void approveReportedStatus(@PathVariable("statusId") String statusId) { log.debug("REST request to approve a status Id : {}", statusId); statusUpdateService.approveReportedStatus(statusId); } /** * GET /statuses/home_timeline -> get the latest statuses from the current user */ @RequestMapping(value = "/rest/statuses/home_timeline", method = RequestMethod.GET, produces = "application/json") @ResponseBody @Timed public Collection<StatusDTO> listStatus(@RequestParam(required = false) Integer count, @RequestParam(required = false) String start, @RequestParam(required = false) String finish) { if (count == null || count == 0) { count = 20; //Default value } try { return timelineService.getTimeline(count, start, finish); } catch (Exception e) { StringWriter stack = new StringWriter(); PrintWriter pw = new PrintWriter(stack); e.printStackTrace(pw); log.debug("{}", stack.toString()); return null; } } /** * GET /statuses/user_timeline?screen_name=jdubois -> get the latest statuses from user "jdubois" */ @RequestMapping(value = "/rest/statuses/{username}/timeline", method = RequestMethod.GET, produces = "application/json") @ResponseBody public Collection<StatusDTO> listStatusForUser(@PathVariable("username") String username, @RequestParam(required = false) Integer count, @RequestParam(required = false) String start, @RequestParam(required = false) String finish) { if (count == null || count == 0) { count = 20; //Default value } log.debug("REST request to get someone's status (username={}).", username); if (username == null || username.length() == 0) { return new ArrayList<StatusDTO>(); } try { return timelineService.getUserline(username, count, start, finish); } catch (Exception e) { if (log.isDebugEnabled()) { e.printStackTrace(); } return new ArrayList<StatusDTO>(); } } @RequestMapping(value = "/rest/statuses/{statusId}", method = RequestMethod.GET, produces = "application/json") @ResponseBody public StatusDTO getStatus(@PathVariable("statusId") String statusId) { log.debug("REST request to get status Id : {}", statusId); return timelineService.getStatus(statusId); } @RequestMapping(value = "/rest/statuses/{statusId}", method = RequestMethod.DELETE) public void deleteStatus(@PathVariable("statusId") String statusId) { log.debug("REST request to get status Id : {}", statusId); timelineService.removeStatus(statusId); } @RequestMapping(value = "/rest/statuses/{statusId}", method = RequestMethod.PATCH) @ResponseBody public StatusDTO updateStatus(@RequestBody ActionStatus action, @PathVariable("statusId") String statusId) { try { StatusDTO status = timelineService.getStatus(statusId); if (action.isFavorite() != null && status.isFavorite() != action.isFavorite()) { if (action.isFavorite()) { timelineService.addFavoriteStatus(statusId); } else { timelineService.removeFavoriteStatus(statusId); } status.setFavorite(action.isFavorite()); } if (action.isShared() != null && action.isShared()) { timelineService.shareStatus(statusId); status.setShareByMe(action.isShared()); } if (action.isAnnounced() != null && action.isAnnounced()) { timelineService.announceStatus(statusId); } return status; } catch (Exception e) { StringWriter stack = new StringWriter(); PrintWriter pw = new PrintWriter(stack); e.printStackTrace(pw); log.debug("{}", stack.toString()); return null; } } /** * POST /statuses/ -> create a new Status */ @RequestMapping(value = "/rest/statuses/", method = RequestMethod.POST, produces = "application/json") @Timed public String postStatus(@RequestBody StatusDTO status, HttpServletResponse response) throws ArchivedGroupException, ReplyStatusException { log.debug("REST request to add status : {}", status.getContent()); String escapedContent = StringEscapeUtils.escapeHtml(status.getContent()); Collection<String> attachmentIds = status.getAttachmentIds(); if (status.getReplyTo() != null && !status.getReplyTo().isEmpty()) { log.debug("Creating a reply to : {}", status.getReplyTo()); statusUpdateService.replyToStatus(escapedContent, status.getReplyTo(), attachmentIds); } else if (status.isStatusPrivate() || status.getGroupId() == null || status.getGroupId().equals("")) { log.debug("Private status"); statusUpdateService.postStatus(escapedContent, status.isStatusPrivate(), attachmentIds, status.getGeoLocalization()); } else { User currentUser = authenticationService.getCurrentUser(); Collection<Group> groups = groupService.getGroupsForUser(currentUser); Group group = null; for (Group testGroup : groups) { if (testGroup.getGroupId().equals(status.getGroupId())) { group = testGroup; break; } } if (group == null) { log.info("Permission denied! User {} tried to access " + "group ID = {}", currentUser.getLogin(), status.getGroupId()); response.setStatus(HttpServletResponse.SC_FORBIDDEN); } else if (group.isArchivedGroup()) { log.info("Archived group! User {} tried to post a message to archived " + "group ID = {}", currentUser.getLogin(), status.getGroupId()); response.setStatus(HttpServletResponse.SC_FORBIDDEN); } else { statusUpdateService.postStatusToGroup(escapedContent, group, attachmentIds, status.getGeoLocalization()); } } return "{}"; } /** * POST /statuses/hide -> hide the status from the current user timeline */ @RequestMapping(value = "/rest/statuses/hide/{statusId}", method = RequestMethod.POST) public void hideStatus(@PathVariable("statusId") String statusId) { log.debug("REST request to hide status Id : {}", statusId); timelineService.hideStatus(statusId); } }