package org.fluxtream.core.api; import com.google.gson.Gson; import com.wordnik.swagger.annotations.ApiOperation; import com.wordnik.swagger.annotations.ApiParam; import org.fluxtream.core.OutsideTimeBoundariesException; import org.fluxtream.core.SimpleTimeInterval; import org.fluxtream.core.TimeInterval; import org.fluxtream.core.TimeUnit; import org.fluxtream.core.auth.AuthHelper; import org.fluxtream.core.connectors.Connector; import org.fluxtream.core.domain.Guest; import org.fluxtream.core.metadata.DayMetadata; import org.fluxtream.core.mvc.models.PhotoModel; import org.fluxtream.core.services.GuestService; import org.fluxtream.core.services.MetadataService; import org.fluxtream.core.services.PhotoService; import org.fluxtream.core.services.SettingsService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.PathParam; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.text.DecimalFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.List; import java.util.SortedSet; @Path("/v1/guest/{username}/photo") @Component("RESTPhotoStore") // WARNING: WE CAN'T DOCUMENT AN API WITH A WILDCARD IN ITS BASE PATH WITH SWAGGER-UI APPARENTLY @Scope("request") public class PhotoStore { private Gson gson = new Gson(); @Autowired SettingsService settingsService; @Autowired GuestService guestService; @Autowired PhotoService photoService; @Autowired MetadataService metadataService; @GET @Path("/date/{date}") @Produces({MediaType.APPLICATION_JSON}) @ApiOperation(value = "Get the user's photos for a specific date", responseContainer = "Array", response = PhotoModel.class) public Response getPhotosForDate(@ApiParam(value="Username (must be currently logged in user's username)", required=true) @PathParam("username") String username, @ApiParam(value="Date (yyyy-mm-dd)", required=true) @PathParam("date") String date){ try{ Guest guest = guestService.getGuest(username); if (AuthHelper.getGuest().getId()!=guest.getId()) throw new RuntimeException("Attempt to access another user's photos"); DayMetadata dayMeta = metadataService.getDayMetadata(guest.getId(), date); return Response.ok(gson.toJson(getPhotos(guest, dayMeta.getTimeInterval()))).build(); } catch (Exception e){ return Response.serverError().entity("Could not get guest addresses: " + e.getMessage()).build(); } } @GET @Path("/week/{year}/{week}") @Produces({MediaType.APPLICATION_JSON}) @ApiOperation(value = "Get the user's photos for a specific date", responseContainer = "Array", response = PhotoModel.class) public Response getPhotosForWeek(@ApiParam(value="Username (must be currently logged in user's username)", required=true) @PathParam("username") String username, @ApiParam(value="Year", required=true) @PathParam("year") int year, @ApiParam(value="Week", required=true) @PathParam("week") int week){ try{ Calendar c = Calendar.getInstance(); c.set(Calendar.YEAR,year); c.set(Calendar.WEEK_OF_YEAR,week); c.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); Guest guest = guestService.getGuest(username); if (AuthHelper.getGuest().getId()!=guest.getId()) throw new RuntimeException("Attempt to access another user's photos"); DecimalFormat datePartFormat = new DecimalFormat("00"); DayMetadata dayMetaStart = metadataService.getDayMetadata(guest.getId(), year + "-" + datePartFormat.format(c.get(Calendar.MONTH) + 1) + "-" + datePartFormat.format(c.get(Calendar.DAY_OF_MONTH))); int newDay = c.get(Calendar.DAY_OF_YEAR) + 6; if (newDay > (isLeapYear(year) ? 366 : 365)){ newDay -= isLeapYear(year) ? 366 : 365; year += 1; c.set(Calendar.YEAR,year); } c.set(Calendar.DAY_OF_YEAR,newDay); DayMetadata dayMetaEnd = metadataService.getDayMetadata(guest.getId(), year + "-" + datePartFormat.format(c.get(Calendar.MONTH) + 1) + "-" + datePartFormat.format(c.get(Calendar.DAY_OF_MONTH))); return Response.ok(gson.toJson(getPhotos(guest, new SimpleTimeInterval(dayMetaStart.start,dayMetaEnd.end,TimeUnit.WEEK,dayMetaStart.getTimeInterval().getMainTimeZone())))).build(); } catch (Exception e){ return Response.serverError().entity("Could not get photos: " + e.getMessage()).build(); } } @GET @Path("/year/{year}") @Produces({MediaType.APPLICATION_JSON}) @ApiOperation(value = "Get the user's photos for an entire year", responseContainer = "Array", response = PhotoModel.class) public Response getPhotosForYear(@ApiParam(value="Username (must be currently logged in user's username)", required=true) @PathParam("username") String username, @ApiParam(value="Year", required=true) @PathParam("year") int year){ try{ Guest guest = guestService.getGuest(username); if (AuthHelper.getGuest().getId()!=guest.getId()) throw new RuntimeException("Attempt to access another user's photos"); DayMetadata dayMetaStart = metadataService.getDayMetadata(guest.getId(), year + "-01-01"); DayMetadata dayMetaEnd = metadataService.getDayMetadata(guest.getId(), year + "-12-31"); return Response.ok(gson.toJson(getPhotos(guest, new SimpleTimeInterval(dayMetaStart.start,dayMetaEnd.end,TimeUnit.YEAR,dayMetaStart.getTimeInterval().getMainTimeZone())))).build(); } catch (Exception e){ return Response.serverError().entity("Could not get photos: " + e.getMessage()).build(); } } private boolean isLeapYear(int year){ if (year % 400 == 0) return true; if (year % 100 == 0) return false; return year % 4 == 0; } private List<PhotoModel> getPhotos(Guest guest, TimeInterval timeInterval) throws ClassNotFoundException, IllegalAccessException, InstantiationException, OutsideTimeBoundariesException { final SortedSet<PhotoService.Photo> photos = photoService.getPhotos(guest.getId(), timeInterval, Connector.getConnector("fluxtream_capture").prettyName(), "photo", null); List<PhotoModel> photoModels = new ArrayList<PhotoModel>(); for (final PhotoService.Photo photo : photos) { photoModels.add(new PhotoModel(photo.getAbstractPhotoFacetVO())); } return photoModels; } }