/* * Copyright 2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.springsource.greenhouse.events; import java.util.List; import javax.inject.Inject; import org.joda.time.DateTime; import org.joda.time.DateTimeZone; import org.joda.time.LocalDate; import org.springframework.format.annotation.DateTimeFormat; import org.springframework.format.annotation.DateTimeFormat.ISO; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.social.twitter.api.SearchResults; import org.springframework.social.twitter.api.Twitter; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; 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.ResponseBody; import com.springsource.greenhouse.account.Account; import com.springsource.greenhouse.utils.Location; /** * UI Controller for Event actions. * @author Keith Donald */ @Controller public class EventsController { private final EventRepository eventRepository; private final Twitter twitter; @Inject public EventsController(EventRepository eventRepository, Twitter twitter) { this.eventRepository = eventRepository; this.twitter = twitter; } // for web service (JSON) clients /** * Write the list of upcoming events to the body of the response. * Only matches 'GET /events' requests for JSON content; a 404 is sent otherwise. * TODO send a 406 if an unsupported representation, such as XML, is requested. See SPR-7353. */ @RequestMapping(value="/events", method=RequestMethod.GET, produces="application/json") public @ResponseBody List<Event> upcomingEvents(@RequestParam(value="after", required=false) @DateTimeFormat(iso=ISO.DATE_TIME) Long afterMillis) { return eventRepository.findUpcomingEvents(afterMillis); } /** * Write the list of event favorites to the body of the response. */ @RequestMapping(value="/events/{eventId}/favorites", method=RequestMethod.GET, produces="application/json") public @ResponseBody List<EventSession> favorites(@PathVariable Long eventId, Account account) { return eventRepository.findEventFavorites(eventId, account.getId()); } /** * Write a page of event tweet search results to the body of the response. * The page number and size may be provided by the client. If not specified, defaults to the first page of ten results. */ @RequestMapping(value="/events/{eventId}/tweets", method=RequestMethod.GET, produces="application/json") public @ResponseBody SearchResults tweets(@PathVariable Long eventId, @RequestParam(defaultValue="1") Integer page, @RequestParam(defaultValue="10") Integer pageSize) { String searchString = eventRepository.findEventSearchString(eventId); return searchString != null && searchString.length() > 0 ? twitter.searchOperations().search(searchString, page, pageSize) : null; } /** * Post a tweet about the event to Twitter. * Write OK status back if this is successful. */ @RequestMapping(value="/events/{eventId}/tweets", method=RequestMethod.POST) public ResponseEntity<String> postTweet(@PathVariable Long eventId, @RequestParam String status, Location currentLocation) { twitter.timelineOperations().updateStatus(status); return new ResponseEntity<String>(HttpStatus.OK); } /** * Retweet another event tweet. */ @RequestMapping(value="/events/{eventId}/retweet", method=RequestMethod.POST) public @ResponseBody ResponseEntity<String> postRetweet(@PathVariable Long eventId, @RequestParam Long tweetId) { twitter.timelineOperations().retweet(tweetId); return new ResponseEntity<String>(HttpStatus.OK); } /** * Write the attendee's list of favorite sessions to the body of the response. */ @RequestMapping(value="/events/{eventId}/sessions/favorites", method=RequestMethod.GET, produces="application/json") public @ResponseBody List<EventSession> favoriteSessions(@PathVariable Long eventId, Account account) { return eventRepository.findAttendeeFavorites(eventId, account.getId()); } /** * Write the sessions scheduled for the day to the body of the response. */ @RequestMapping(value="/events/{eventId}/sessions/{day}", method=RequestMethod.GET, produces="application/json") public @ResponseBody List<EventSession> sessionsOnDay(@PathVariable Long eventId, @PathVariable @DateTimeFormat(iso=ISO.DATE) LocalDate day, Account account) { return eventRepository.findSessionsOnDay(eventId, day, account.getId()); } /** * Toggle a session as an attendee favorite. * Write the new favorite status to the body of the response. */ @RequestMapping(value="/events/{eventId}/sessions/{sessionId}/favorite", method=RequestMethod.PUT) public @ResponseBody Boolean toggleFavorite(@PathVariable Long eventId, @PathVariable Integer sessionId, Account account) { return eventRepository.toggleFavorite(eventId, sessionId, account.getId()); } /** * Add or update the rating given to the session by the attendee. * Write the new average rating for the session to the body of the response. */ @RequestMapping(value="/events/{eventId}/sessions/{sessionId}/rating", method=RequestMethod.POST) public @ResponseBody Float updateRating(@PathVariable Long eventId, @PathVariable Integer sessionId, Account account, @RequestParam Short value, @RequestParam String comment) throws RatingPeriodClosedException { return eventRepository.rate(eventId, sessionId, account.getId(), new Rating(value, comment)); } /** * Write a page of session tweet search results to the body of the response. */ @RequestMapping(value="/events/{eventId}/sessions/{sessionId}/tweets", method=RequestMethod.GET, produces="application/json") public @ResponseBody SearchResults sessionTweets(@PathVariable Long eventId, @PathVariable Integer sessionId, @RequestParam(defaultValue="1") Integer page, @RequestParam(defaultValue="10") Integer pageSize) { String searchString = eventRepository.findSessionSearchString(eventId, sessionId); return searchString != null && searchString.length() > 0 ? twitter.searchOperations().search(searchString, page, pageSize) : null; } /** * Post a tweet about a session. */ @RequestMapping(value="/events/{eventId}/sessions/{sessionId}/tweets", method=RequestMethod.POST) public ResponseEntity<String> postSessionTweet(@PathVariable Long eventId, @PathVariable Integer sessionId, @RequestParam String status, Location currentLocation) { twitter.timelineOperations().updateStatus(status); return new ResponseEntity<String>(HttpStatus.OK); } /** * Retweet a session tweet. */ @RequestMapping(value="/events/{eventId}/sessions/{sessionId}/retweet", method=RequestMethod.POST) public @ResponseBody ResponseEntity<String> postSessionRetweet(@PathVariable Long eventId, @PathVariable Integer sessionId, @RequestParam Long tweetId) { twitter.timelineOperations().retweet(tweetId); return new ResponseEntity<String>(HttpStatus.OK); } // for web browser (HTML) clients /** * Render the list of upcoming events as HTML in the client's web browser. */ @RequestMapping(value="/events", method=RequestMethod.GET, produces="text/html") public String upcomingEventsView(Model model, DateTimeZone timeZone) { model.addAttribute(eventRepository.findUpcomingEvents(new DateTime(timeZone).getMillis())); return "events/list"; } }