/** * Exposed as `POST /api/photos`. * * <p>Takes the following payload in the request body. Payload represents a Photo that should be * created. { "id":0, "ownerUserId":0, "ownerDisplayName":"", "ownerProfileUrl":"", * "ownerProfilePhoto":"", "themeId":0, "themeDisplayName":"", "numVotes":0, "voted":false, // * Whether or not the current user has voted on this. "created":0, "fullsizeUrl":"", * "thumbnailUrl":"", "voteCtaUrl":"", // URL for Vote interactive post button. * "photoContentUrl":"" // URL for Google crawler to hit to get info. } * * <p>Returns the following JSON response representing the created Photo. { "id":0, * "ownerUserId":0, "ownerDisplayName":"", "ownerProfileUrl":"", "ownerProfilePhoto":"", * "themeId":0, "themeDisplayName":"", "numVotes":0, "voted":false, // Whether or not the current * user has voted on this. "created":0, "fullsizeUrl":"", "thumbnailUrl":"", "voteCtaUrl":"", // * URL for Vote interactive post button. "photoContentUrl":"" // URL for Google crawler to hit to * get info. } * * <p>Issues the following errors along with corresponding HTTP response codes: 400: "Bad Request" * if the request is missing image data. 401: "Unauthorized request" (if certain parameters are * present in the request) 401: "Access token expired" (there is a logged in user, but he doesn't * have a refresh token and his access token is expiring in less than 100 seconds, get a new token * and retry) 500: "Error while writing app activity: " + error from client library. * * @see javax.servlet.http.HttpServlet#doPost( javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) { try { checkAuthorization(req); List<BlobKey> blobKeys = blobstoreService.getUploads(req).get("image"); BlobKey imageKey = null; if (blobKeys != null) { imageKey = blobKeys.iterator().next(); } if (imageKey == null) { sendError(resp, 400, "Missing image data."); } Long currentUserId = (Long) req.getSession().getAttribute(CURRENT_USER_SESSION_KEY); User author = ofy().load().type(User.class).id(currentUserId).get(); GoogleCredential credential = this.getCredentialFromLoggedInUser(req); Photo photo = new Photo(); photo.setOwnerUserId(author.getId()); photo.setOwnerDisplayName(author.getGoogleDisplayName()); photo.setOwnerProfilePhoto(author.getGooglePublicProfilePhotoUrl()); photo.setOwnerProfileUrl(author.getGooglePublicProfileUrl()); photo.setThemeId(Theme.getCurrentTheme().getId()); photo.setThemeDisplayName(Theme.getCurrentTheme().getDisplayName()); photo.setCreated(Calendar.getInstance().getTime()); photo.setNumVotes(0); photo.setImageBlobKey(imageKey.getKeyString()); ofy().save().entity(photo).now(); ofy().clear(); photo = ofy().load().type(Photo.class).id(photo.getId()).get(); addPhotoToGooglePlusHistory(author, photo, credential); sendResponse(req, resp, photo); } catch (UserNotAuthorizedException e) { sendError(resp, 401, "Unauthorized request"); } catch (MomentWritingException e) { sendError(resp, 500, "Error while writing app activity: " + e.getMessage()); } catch (GoogleTokenExpirationException e) { sendError(resp, 401, "Access token expired"); } }
/** * Exposed as `GET /api/photos`. * * <p>Accepts the following request parameters. * * <p>'photoId': id of the requested photo. Will return a single Photo. 'themeId': id of a theme. * Will return the collection of photos for the specified theme. 'userId': id of the owner of the * photo. Will return the collection of photos for that user. The keyword ‘me’ can be used and * will be converted to the logged in user. Requires auth. 'friends': value evaluated to boolean, * if true will filter only photos from friends of the logged in user. Requires auth. * * <p>Returns the following JSON response representing a list of Photos. * * <p>[ { "id":0, "ownerUserId":0, "ownerDisplayName":"", "ownerProfileUrl":"", * "ownerProfilePhoto":"", "themeId":0, "themeDisplayName":"", "numVotes":0, "voted":false, // * Whether or not the current user has voted on this. "created":0, "fullsizeUrl":"", * "thumbnailUrl":"", "voteCtaUrl":"", // URL for Vote interactive post button. * "photoContentUrl":"" // URL for Google crawler to hit to get info. }, ... ] * * <p>Issues the following errors along with corresponding HTTP response codes: 401: "Unauthorized * request" (if certain parameters are present in the request) * * @see javax.servlet.http.HttpServlet#doGet( javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) { try { BASE_URL = getBaseUrlFromRequest(req); String photoId = req.getParameter("photoId"); String themeId = req.getParameter("themeId"); String userIdParam = req.getParameter("userId"); Long userId; Long currentUserId = null; if (req.getSession().getAttribute(CURRENT_USER_SESSION_KEY) != null) { currentUserId = Long.parseLong(req.getSession().getAttribute(CURRENT_USER_SESSION_KEY).toString()); } boolean showFriends = Boolean.parseBoolean(req.getParameter("friends")); Query<Photo> q = ofy().load().type(Photo.class); if (photoId != null) { // Get the photo with the given ID and return it. Photo photo = q.filter("id", Long.parseLong(photoId)).first().get(); sendResponse(req, resp, photo); } else { if (userIdParam != null) { // If the key word me is used, retrieve the current user from the session // The user needs to be authenticated to use 'me' if (userIdParam.equals("me")) { checkAuthorization(req); userId = currentUserId; } else { userId = Long.parseLong(userIdParam); } if (showFriends) { checkAuthorization(req); // Get all photos for the user's friends. User user = ofy().load().type(User.class).filterKey(User.key(userId)).first().get(); List<Long> friendIds = user.getFriendIds(); if (friendIds.size() > 30) { friendIds = friendIds.subList(0, 30); } if (friendIds.size() > 0) { q = q.filter("ownerUserId in", friendIds); } else { List<Photo> emptyList = new ArrayList<Photo>(); // If there are no friends for the user, return an empty list sendResponse(req, resp, emptyList, "photohunt#photos"); return; } } else { // Get all photos for the user. q = q.filter("ownerUserId", userId); } } if (themeId != null) { // Limit photos to just those for the given theme. q = q.filter("themeId", Long.parseLong(themeId)); } List<Photo> photos = q.list(); if (currentUserId != null) { // Build Hash map of voted photos List<Vote> userVotes = ofy().load().type(Vote.class).filter("ownerUserId", currentUserId).list(); HashMap<Long, Boolean> userVotesTable = new HashMap<Long, Boolean>(userVotes.size()); Iterator<Vote> votesIterator = userVotes.iterator(); while (votesIterator.hasNext()) { userVotesTable.put(votesIterator.next().getPhotoId(), true); } // Check if user voted for each photo Iterator<Photo> photosIterator = photos.iterator(); while (photosIterator.hasNext()) { Photo current = photosIterator.next(); current.setVoted(userVotesTable.containsKey(current.getId())); } } sendResponse(req, resp, photos, "photohunt#photos"); } } catch (UserNotAuthorizedException e) { sendError(resp, 401, "Unauthorized request"); } }