@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String blobKey = req.getParameter("blobKey"); String path = req.getParameter("path"); if (path != null && path.trim().length() > 0) { JsonObject retObj = new JsonObject(); String uploadBlobPath = BlobstoreServiceFactory.getBlobstoreService() .createUploadUrl(URLDecoder.decode(path), UploadOptions.Builder.withDefaults()); retObj.addProperty("result", "success"); retObj.addProperty("path", URLEncoder.encode(uploadBlobPath)); if (retObj.get("result") == null) { retObj.addProperty("result", "fail"); } resp.getWriter().write(retObj.toString()); } else if (blobKey != null) { BlobstoreServiceFactory.getBlobstoreService().serve(new BlobKey(blobKey), resp); } }
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String path = request.getPathInfo(); List<StaticFile> staticFiles = new ArrayList<StaticFile>(); if (path.endsWith("/all")) { staticFiles.addAll(StaticFile.all().order("name").fetch()); } else { StaticFile file = StaticFile.all().filter("path", removeLeadingSlash(path)).get(); if (file != null) { staticFiles.add(file); } } // no caching of json for (StaticFile file : staticFiles) { byte[] fileData = BlobstoreServiceFactory.getBlobstoreService() .fetchData( new BlobKey(file.getBlobKey()), 0, BlobstoreService.MAX_BLOB_FETCH_SIZE - 1); String base64fileData = Base64.encodeBase64URLSafeString(fileData); // UTF-8, JSON-safe file.setData(base64fileData); } response.setContentType("application/json"); response.setStatus(200); PrintWriter out = response.getWriter(); out.print(new JsonResponse(staticFiles).toJson()); }
@InSequence(10) @Test @OperateOnDeployment("dep1") public void insertIntoBlobstoreOnDep1() throws Exception { BlobstoreService service = BlobstoreServiceFactory.getBlobstoreService(); FileService fileService = FileServiceFactory.getFileService(); AppEngineFile file = fileService.createNewBlobFile("text/plain", "uploadedText.txt"); FileWriteChannel channel = fileService.openWriteChannel(file, true); try { channel.write(ByteBuffer.wrap(TEXT.getBytes())); } finally { channel.closeFinally(); } waitForSync(); BlobKey blobKey = fileService.getBlobKey(file); System.out.println("Blob key: " + blobKey); byte[] bytes = service.fetchData(blobKey, 0, Long.MAX_VALUE); Assert.assertEquals(TEXT, new String(bytes)); DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); Entity dsBK = new Entity("blobTestId", 1); dsBK.setProperty("blogId", blobKey.getKeyString()); ds.put(dsBK); waitForSync(); }
/** * A Controller version that contains utilities methods to handler the GAE Blobstore facilities. * * @author Danilo Queiroz - [email protected] */ public abstract class BlobstoreController extends Controller { private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); /** * Gets the blobservice upload url. * * @param successPath The url to blobservice redirect after a successful upload. * @return the blobservice upload url. */ protected final String uploadUrl(String successPath) { return this.blobstoreService.createUploadUrl(successPath); } /** * Gets the {@link BlobKey} a uploaded file. * * @param file the uploaded file's name - the name used by the form to define the file * @return The {@link BlobKey} fot the given file, or <code>null</code> if there's no file * uploaded with the given name * @throws IllegalStateException If not called from a blob upload callback request. */ protected final BlobKey blobKey(String file) { return this.blobstoreService.getUploadedBlobs(this.request()).get(file); } /** * Serves a file with the given {@link BlobKey} * * @param blobKey the file's {@link BlobKey} */ protected final void serve(String blobKey) { this.setControllerResponse(new BlobResponse(blobstoreService, new BlobKey(blobKey))); } }
public class BlobStoreServletWithExternalUrl extends HttpServlet { private static final Logger log = Logger.getLogger(BlobStoreServletWithExternalUrl.class.getName()); private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException { res.setHeader("Cache-Control", "max-age=2592000"); BlobKey blobKey = new BlobKey(req.getParameter("blob-key")); blobstoreService.serve(blobKey, res); } protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { try { Long runId = null; String account = null; String fileName = null; runId = Long.parseLong(req.getParameter("runId")); account = req.getParameter("account"); fileName = req.getParameter("fileName"); if (req.getParameter("withBlob") == null) { // UploadOptions uploadOptions = // UploadOptions.Builder.withGoogleStorageBucketName("streetlearn"); //TODO this was added String uploadUrl = blobstoreService.createUploadUrl( "/uploadServiceWithUrl?withBlob=true&runId=" + runId + "&account=" + account + "&fileName=" + fileName); // TODO this was the old one // String uploadUrl = // blobstoreService.createUploadUrl("/uploadServiceWithUrl?withBlob=true&runId=" + runId + // "&account=" + account + "&fileName=" + fileName, uploadOptions); res.getWriter().write(uploadUrl); } else { // GcsService gcsService = GcsServiceFactory.createGcsService(new // RetryParams.Builder() // .initialRetryDelayMillis(10) // .retryMaxAttempts(10) // .totalRetryPeriodMillis(15000) // .build()); java.util.Map<java.lang.String, java.util.List<BlobKey>> blobs = blobstoreService.getUploads(req); for (String key : blobs.keySet()) { FilePathManager.addFile(runId, account, fileName, blobs.get(key).get(0)); } } } catch (Exception ex) { throw new ServletException(ex); } } }
@Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String blobKey = req.getParameter("blobKey"); JsonObject retObj = new JsonObject(); if (blobKey != null) { BlobstoreServiceFactory.getBlobstoreService().delete(new BlobKey(blobKey)); retObj.addProperty("result", "success"); } if (retObj.get("result") == null) { retObj.addProperty("result", "fail"); } resp.getWriter().write(retObj.toString()); }
private static BlobKey getBlobkKey(ImageRef ref) { ImageStore store = new ImageStore(); store.init(); Optional<StoredImage> image = store.tryLoadImage(ref); if (image.isPresent()) { log.info("Using blobkey: " + image.get().getBlobKey()); return new BlobKey(image.get().getBlobKey()); } else { GcsFilename oldGcsFileName = createOldGcsFileName(ref.getReportId(), ref.getImageName()); log.info("Using old GCS fileName: " + oldGcsFileName.toString()); BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); // Does not work on dev server. return blobstoreService.createGsBlobKey( "/gs/" + oldGcsFileName.getBucketName() + "/" + oldGcsFileName.getObjectName()); } }
private void remove(String encoded, HttpServletResponse response) throws IOException { BlobstoreService blobstore = BlobstoreServiceFactory.getBlobstoreService(); DatastoreService datastore = DS.get(); Key key = KeyFactory.stringToKey(encoded); Transaction tr = datastore.beginTransaction(); try { Entity blog = datastore.get(key); datastore.delete(key); response.setContentType("text/plain"); PrintWriter writer = response.getWriter(); writer.println("Deleted blog: " + blog.getProperty("Subject")); tr.commit(); } catch (EntityNotFoundException ex) { throw new IOException(ex); } finally { if (tr.isActive()) { tr.rollback(); } } }
@Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { BlobstoreService bs = BlobstoreServiceFactory.getBlobstoreService(); Map<String, List<BlobKey>> blobs = bs.getUploads(req); List<BlobKey> imageBlobs = blobs.get("source"); JsonObject retObj = new JsonObject(); if (imageBlobs.size() > 0) { BlobKey image = imageBlobs.get(0); retObj.addProperty("result", "success"); retObj.addProperty("blobKey", image.getKeyString()); } if (retObj.get("result") == null) { retObj.addProperty("result", "fail"); } resp.getWriter().write(retObj.toString()); }
@InSequence(20) @Test @OperateOnDeployment("dep2") public void readFromBlobstoreOnDep2() throws Exception { DatastoreService ds = DatastoreServiceFactory.getDatastoreService(); Key key = KeyFactory.createKey("blobTestId", 1); Entity dsBK = ds.get(key); String blobKeyStr = (String) dsBK.getProperty("blogId"); BlobKey blobKey = new BlobKey(blobKeyStr); if (blobKeyStr == null || blobKeyStr.equals("")) { fail("Datastore should have this value. Try to run clustered DatastoreTestCase first."); } BlobstoreService service = BlobstoreServiceFactory.getBlobstoreService(); System.out.println("Blob key: " + blobKey); byte[] bytes = service.fetchData(blobKey, 0, Long.MAX_VALUE); try { Assert.assertEquals(TEXT, new String(bytes)); } finally { service.delete(blobKey); } }
private Future<HTTPResponse> postBlobs( String filename, String contentType, String sha1, byte[] data, String metadataSize, HttpServletRequest request, int width, int height) throws MessagingException, IOException { try { URLFetchService fetchService = URLFetchServiceFactory.getURLFetchService(); BlobstoreService blobstore = BlobstoreServiceFactory.getBlobstoreService(); URI reqUri = new URI(request.getScheme(), request.getServerName(), "", ""); URI uri = reqUri.resolve( "/blob?" + NamespaceParameter + "=" + NamespaceManager.get() + "&" + SizeParameter + "=" + metadataSize + "&" + WidthParameter + "=" + width + "&" + HeightParameter + "=" + height); URL uploadUrl = new URL(blobstore.createUploadUrl(uri.toASCIIString())); log("post blob to " + uploadUrl); HTTPRequest httpRequest = new HTTPRequest(uploadUrl, HTTPMethod.POST, FetchOptions.Builder.withDeadline(60)); String uid = UUID.randomUUID().toString(); httpRequest.addHeader(new HTTPHeader("Content-Type", "multipart/form-data; boundary=" + uid)); ByteArrayOutputStream baos = new ByteArrayOutputStream(); PrintStream ps = new PrintStream(baos); ps.append("--" + uid); ps.append(CRLF); ps.append( "Content-Disposition: form-data; name=\"" + sha1 + "\"; filename=\"" + filename + "\""); ps.append(CRLF); ps.append("Content-Type: " + contentType); ps.append(CRLF); ps.append("Content-Transfer-Encoding: binary"); ps.append(CRLF); ps.append(CRLF); ps.write(data); ps.append(CRLF); ps.append("--" + uid + "--"); ps.append(CRLF); ps.close(); log("sending blob size=" + baos.size()); httpRequest.setPayload(baos.toByteArray()); return fetchService.fetchAsync(httpRequest); } catch (URISyntaxException ex) { throw new IOException(ex); } }
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { int index; DatastoreService ds; MemcacheService ms; BlobstoreService bs; URLFetchService us; FileService fs; Map<String, List<BlobKey>> blobMap; BlobKey blobKey; BlobInfoFactory blobInfoFactory; BlobInfo blobInfo; int postCount; int postIndex; String postType; String postText; String postDelpw; String postShowgallery; DataObj dataObj; String filelink; String picUrl; HTTPResponse picRes; List<HTTPHeader> headerList; String picMime; String[] fileNamePart; AppEngineFile picFile; FileWriteChannel writeChannel; PostObj postObj; List<PostObj> postObjList; String linkID; resp.setCharacterEncoding("UTF-8"); resp.setContentType("text/plain"); try { ds = DatastoreServiceFactory.getDatastoreService(); ms = MemcacheServiceFactory.getMemcacheService(); bs = BlobstoreServiceFactory.getBlobstoreService(); us = URLFetchServiceFactory.getURLFetchService(); fs = FileServiceFactory.getFileService(); blobInfoFactory = new BlobInfoFactory(ds); blobMap = bs.getUploads(req); postCount = Integer.valueOf(req.getParameter("input_post_count")); postObjList = new ArrayList<PostObj>(); for (postIndex = 0; postIndex < postCount; postIndex++) { try { postType = req.getParameter("input_post_type_" + postIndex); if (postType == null) { continue; } postText = req.getParameter("input_post_text_" + postIndex); postDelpw = req.getParameter("input_post_delpw_" + postIndex); postShowgallery = req.getParameter("input_post_showgallery_" + postIndex); if (postShowgallery == null) { postShowgallery = ""; } if (postType.equals("file") == true) { blobKey = blobMap.get("input_post_file_" + postIndex).get(0); if (blobKey == null) { throw new Exception(); } dataObj = new DataObj(); dataObj.fileid = createUID(); dataObj.posttime = new Date().getTime(); dataObj.delpw = postDelpw; dataObj.blobkey = blobKey; dataObj.putDB(ds); blobInfo = blobInfoFactory.loadBlobInfo(dataObj.blobkey); filelink = "http://" + req.getServerName() + "/down/" + dataObj.fileid + "/" + blobInfo.getFilename(); postObj = new PostObj( dataObj.fileid, filelink, blobInfo.getSize(), dataObj.posttime, dataObj.delpw, postShowgallery); postObjList.add(postObj); } else if (postType.equals("url") == true) { picUrl = postText; picRes = us.fetch(new URL(picUrl)); headerList = picRes.getHeaders(); picMime = "application/octet-stream"; for (index = 0; index < headerList.size(); index++) { if (headerList.get(index).getName().compareToIgnoreCase("Content-Type") == 0) { picMime = headerList.get(index).getValue(); break; } } fileNamePart = picUrl.split("/"); picFile = fs.createNewBlobFile(picMime, fileNamePart[fileNamePart.length - 1]); writeChannel = fs.openWriteChannel(picFile, true); writeChannel.write(ByteBuffer.wrap(picRes.getContent())); writeChannel.closeFinally(); dataObj = new DataObj(); dataObj.fileid = createUID(); dataObj.posttime = new Date().getTime(); dataObj.delpw = postDelpw; dataObj.blobkey = fs.getBlobKey(picFile); dataObj.putDB(ds); blobInfo = blobInfoFactory.loadBlobInfo(dataObj.blobkey); filelink = "http://" + req.getServerName() + "/down/" + dataObj.fileid + "/" + blobInfo.getFilename(); postObj = new PostObj( dataObj.fileid, filelink, blobInfo.getSize(), dataObj.posttime, dataObj.delpw, postShowgallery); postObjList.add(postObj); } } catch (Exception e) { } } linkID = postFile(us, postObjList); if (req.getParameter("specflag") != null) { resp.getWriter().print("http://tnfshmoe.appspot.com/link.jsp?linkid=" + linkID); } else { resp.sendRedirect("http://tnfshmoe.appspot.com/link.jsp?linkid=" + linkID); } } catch (Exception e) { } }
public class FileContent extends HttpServlet { private BlobstoreService bService = BlobstoreServiceFactory.getBlobstoreService(); public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException { String fileName = null; long startTime, endTime; String fileContentToDisplay = req.getParameter("FileToDisplay"); res.getWriter().println("File conetent to be displayed : " + fileContentToDisplay); startTime = System.currentTimeMillis(); // Find if the file is in memcache. If present there is no need to go to blobstore to get the // data MemcacheService mService = MemcacheServiceFactory.getMemcacheService(); AppEngineFile readableFile; readableFile = (AppEngineFile) mService.get(fileName); if (readableFile != null) { FileService fService = FileServiceFactory.getFileService(); res.getWriter().println("File " + fileName + " is present in cache"); FileReadChannel readChannel = fService.openReadChannel(readableFile, false); BufferedReader reader = new BufferedReader(Channels.newReader(readChannel, "UTF8")); String line = null; res.getWriter().println("Contents of the file: "); while ((line = reader.readLine()) != null) { res.getWriter().println(line + "<br>"); } readChannel.close(); } else // Search for the file in blob { List<BlobInfo> blobToRead = new LinkedList<BlobInfo>(); Iterator<BlobInfo> blobIterator = new BlobInfoFactory().queryBlobInfos(); while (blobIterator.hasNext()) blobToRead.add(blobIterator.next()); res.setContentType("text/plain"); Boolean filePresent = false; int i; for (i = 0; i < blobToRead.size(); i++) { fileName = blobToRead.get(i).getFilename(); if (fileName.equals(fileContentToDisplay)) { FileService fService = FileServiceFactory.getFileService(); res.getWriter().println("File " + fileName + " is present in the blob store"); readableFile = fService.getBlobFile(blobToRead.get(i).getBlobKey()); FileReadChannel readChannel = fService.openReadChannel(readableFile, false); BufferedReader reader = new BufferedReader(Channels.newReader(readChannel, "UTF8")); String line = null; res.getWriter().println("printing the contents : "); while ((line = reader.readLine()) != null) { res.getWriter().println(line); } readChannel.close(); } else { res.getWriter().println("File " + fileName + " is not present in the blob store"); } } } endTime = System.currentTimeMillis(); res.getWriter().println("Time taken for the operation is " + (endTime - startTime) + " ms"); } }
/** * Provides an API for working with Photos. This servlet provides the /api/photos endpoint, and * exposes the following operations: * * <p>GET /api/photos GET /api/photos?photoId=1234 GET /api/photos?themeId=1234 GET * /api/photos?userId=me GET /api/photos?themeId=1234&userId=me GET * /api/photos?themeId=1234&userId=me&friends=true POST /api/photos DELETE /api/photos?photoId=1234 * * @author [email protected] (Vic Fryzel) */ public class PhotosServlet extends JsonRestServlet { /** Base URL of the /api/photos end-point. Initialized for every GET request. */ public static String BASE_URL; /** BlobstoreService from which to fetch image information after an Image upload. */ private final BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); /** * 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"); } } /** * 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 `DELETE /api/photos`. * * <p>Accepts the following request parameters. * * <p>'photoId': id of the photo to delete. * * <p>Returns the following JSON response representing success. "Photo successfully deleted." * * <p>Issues the following errors along with corresponding HTTP response codes: 401: "Unauthorized * request" (if certain parameters are present in the request) 404: "Photo with given ID does not * exist." * * @see javax.servlet.http.HttpServlet#doDelete( javax.servlet.http.HttpServletRequest, * javax.servlet.http.HttpServletResponse) */ @Override protected void doDelete(HttpServletRequest req, HttpServletResponse resp) { final String doesNotExist = "Photo with given ID does not exist."; try { checkAuthorization(req); Long photoId = Long.parseLong(req.getParameter("photoId")); Photo photo = ofy().load().key(Photo.key(photoId)).safeGet(); Long userId = Long.parseLong(req.getSession().getAttribute(CURRENT_USER_SESSION_KEY).toString()); if (!userId.equals(photo.getOwnerUserId())) { throw new NotFoundException(); } ofy().delete().entity(photo).now(); List<Vote> photoVotes = ofy().load().type(Vote.class).filter("photoId", photoId).list(); ofy().delete().entities(photoVotes); sendResponse(req, resp, new Message("Photo successfully deleted"), "photohunt#message"); } catch (NotFoundException nfe) { sendError(resp, 404, doesNotExist); } catch (NumberFormatException e) { sendError(resp, 404, doesNotExist); } catch (UserNotAuthorizedException e) { sendError(resp, 401, "Unauthorized request"); } } /** * Creates an app activity in Google indicating that the given User has uploaded the given Photo. * * @param author Creator of Photo. * @param photo Photo itself. * @param credential Credential with which to authorize request to Google. * @throws MomentWritingException Failed to write app activity. */ private void addPhotoToGooglePlusHistory(User author, Photo photo, GoogleCredential credential) throws MomentWritingException { ItemScope target = new ItemScope().setUrl(photo.getPhotoContentUrl()); Moment content = new Moment().setType("http://schemas.google.com/AddActivity").setTarget(target); Plus plus = new Plus.Builder(TRANSPORT, JSON_FACTORY, credential).build(); try { Insert request = plus.moments().insert(author.googleUserId, "vault", content); Moment moment = request.execute(); } catch (IOException e) { throw new MomentWritingException(e.getMessage()); } } /** * @param req Request from which to fetch base URL. * @return Base URL from the given request. */ private String getBaseUrlFromRequest(HttpServletRequest req) { return req.getScheme() + "://" + req.getServerName() + ((req.getServerPort() != 80) ? (":" + req.getServerPort()) : ""); } /** Thrown when writing app activity to Google fails. */ public static class MomentWritingException extends Exception { public MomentWritingException(String message) { super(message); } } }
public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException { if (DEBUG) System.out.println("an ajax call was made!"); boolean namesAdded = false; StringBuilder sb = new StringBuilder(); int maxResults = 10; double maxDistance = 0.0; // meters // using 0 will return all distances up to max # of results double lat = 0.0; double lng = 0.0; String callType = req.getParameter("callType"); String cuisine = req.getParameter("cuisineID"); String category = req.getParameter("categoryID"); String price = req.getParameter("priceID"); String lifestyle = req.getParameter("lifestyleID"); String distanceS = req.getParameter("distance"); String pageNumS = req.getParameter("page"); // lat = Double.parseDouble(req.getParameter("lat")); // lng = Double.parseDouble(req.getParameter("lng")); String distString = req.getParameter("distance"); if (null != distString && distString.length() > 0) maxDistance = Integer.parseInt(distString); maxResults = Integer.parseInt(req.getParameter("maxResults")); Point userLoc = TDUserService.getUserLocation(req); // TDPoint tdpoint=TDUserService.getUserLocation(req); lat = userLoc.getLat(); lng = userLoc.getLon(); long priceID = 0; long categoryID = 0; long lifestyleID = 0; long cuisineID = 0; int pageNum = 0; try { priceID = Long.parseLong(price); if (DEBUG) System.out.println("price found: " + priceID); } catch (NumberFormatException e) { // not a long // e.printStackTrace(); } try { cuisineID = Long.parseLong(cuisine); if (DEBUG) System.out.println("cuisine found: " + cuisineID); } catch (NumberFormatException e) { // not a long // e.printStackTrace(); } try { categoryID = Long.parseLong(category); if (DEBUG) System.out.println("category found: " + categoryID); } catch (NumberFormatException e) { // not a long // e.printStackTrace(); } try { maxDistance = Double.parseDouble(distanceS); if (DEBUG) System.out.println("distance found: " + maxDistance); } catch (NumberFormatException e) { // not a long // e.printStackTrace(); } try { lifestyleID = Long.parseLong(lifestyle); if (DEBUG) System.out.println("lifestyle found: " + lifestyleID); } catch (NumberFormatException e) { // not a long // e.printStackTrace(); } try { pageNum = Integer.parseInt(pageNumS); if (DEBUG) System.out.println("page number found: " + pageNum); } catch (NumberFormatException e) { // not a long // e.printStackTrace(); } // compute distance from miles to meters maxDistance *= 1609.334; Tag categoryTag = null; Tag priceTag = null; Tag lifestyleTag = null; Tag cuisineTag = null; ArrayList<Key> tagKeysToFilter = new ArrayList<Key>(); if (category != null && !category.equals("")) { categoryTag = (Tag) PMF.get().getPersistenceManager().getObjectById(Tag.class, categoryID); tagKeysToFilter.add(categoryTag.getKey()); } if (price != null && !price.equals("")) { priceTag = (Tag) PMF.get().getPersistenceManager().getObjectById(Tag.class, priceID); tagKeysToFilter.add(priceTag.getKey()); } if (lifestyle != null && !lifestyle.equals("")) { lifestyleTag = (Tag) PMF.get().getPersistenceManager().getObjectById(Tag.class, lifestyleID); tagKeysToFilter.add(lifestyleTag.getKey()); } if (cuisine != null && !cuisine.equals("")) { cuisineTag = (Tag) PMF.get().getPersistenceManager().getObjectById(Tag.class, cuisineID); tagKeysToFilter.add(cuisineTag.getKey()); } List<Dish> dishResults = null; if (null != callType && callType.equals("search")) { String query = req.getParameter("searchWord"); if (query.isEmpty()) query = " "; query = query.toLowerCase(); String[] qWords = query.split(" "); dishResults = TDQueryUtils.searchGeoItemsWithFilter( qWords, userLoc, maxResults, maxDistance, new Dish(), pageNum * maxResults, tagKeysToFilter, new DishPosReviewsComparator()); } else { dishResults = AbstractSearch.filterDishes( PMF.get().getPersistenceManager(), maxResults, tagKeysToFilter, maxDistance, lat, lng, pageNum * maxResults, new DishPosReviewsComparator()); } if (null != dishResults && dishResults.size() > 0) { if (DEBUG) System.out.println("result set size: " + dishResults.size()); sb.append("<DishSearch>"); sb.append("<count>" + pageNum + "</count>"); sb.append("<Dishes>"); namesAdded = true; for (Dish dish : dishResults) { Restaurant r = PMF.get().getPersistenceManager().getObjectById(Restaurant.class, dish.getRestaurant()); List<Tag> tags = TDQueryUtils.getAll(dish.getTags(), new Tag()); Photo dishPhoto = null; if (dish.getPhotos() != null && dish.getPhotos().size() > 0) { dishPhoto = PMF.get().getPersistenceManager().getObjectById(Photo.class, dish.getPhotos().get(0)); } int vote = 0; try { if (TDUserService.getUserLoggedIn()) vote = TDUserService.getUserVote( TDUserService.getUser(PMF.get().getPersistenceManager()).getKey(), dish.getKey()); } catch (UserNotLoggedInException e) { // e.printStackTrace(); } catch (UserNotFoundException e) { // e.printStackTrace(); } BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); String blobUploadURL = blobstoreService.createUploadUrl("/addReview"); sb.append("<Dish>"); sb.append("<blobUploadURL>" + blobUploadURL + "</blobUploadURL>"); sb.append("<keyId>" + dish.getKey().getId() + "</keyId>"); sb.append("<name>" + StringEscapeUtils.escapeHtml(dish.getName()) + "</name>"); sb.append( "<description>" + StringEscapeUtils.escapeHtml(dish.getDescription()) + "</description>"); sb.append( "<distance>" + TDMathUtils.formattedGeoPtDistanceMiles(userLoc, dish.getLocation()) + "</distance>"); boolean isEditable = false; if (TDUserService.getUserLoggedIn() && UserServiceFactory.getUserService().isUserAdmin()) { isEditable = true; } else isEditable = TDQueryUtils.isAccessible(Long.valueOf(dish.getKey().getId()), new Dish()); if (isEditable) sb.append("<allowEdit>T</allowEdit>"); else sb.append("<allowEdit>F</allowEdit>"); if (TDUserService.getUserLoggedIn()) { sb.append("<userLoggedIn>L</userLoggedIn>"); } else { sb.append("<userLoggedIn>O</userLoggedIn>"); } if (null != dishPhoto) { try { sb.append( "<blobKey>" + ImagesServiceFactory.getImagesService() .getServingUrl(dishPhoto.getBlobKey(), 98, true) + "</blobKey>"); sb.append("<photoExist>E</photoExist>"); } catch (Exception e) { sb.append("<photoExist>NE</photoExist>"); } } else { sb.append("<blobKey></blobKey>"); sb.append("<photoExist>NE</photoExist>"); } sb.append( "<restAddrLine1>" + StringEscapeUtils.escapeHtml(r.getAddressLine1()) + "</restAddrLine1>"); sb.append("<restCity>" + StringEscapeUtils.escapeHtml(r.getCity()) + "</restCity>"); sb.append("<restState>" + StringEscapeUtils.escapeHtml(r.getState()) + "</restState>"); sb.append("<restId>" + r.getKey().getId() + "</restId>"); sb.append("<restName>" + StringEscapeUtils.escapeHtml(r.getName()) + "</restName>"); sb.append( "<restNeighbourhood>" + StringEscapeUtils.escapeHtml(r.getNeighborhood()) + "</restNeighbourhood>"); // sb.append("<location>" + dish.getLocation() + "</location>"); sb.append("<latitude>" + dish.getLocation().getLat() + "</latitude>"); sb.append("<longitude>" + dish.getLocation().getLon() + "</longitude>"); sb.append("<posReviews>" + dish.getNumPosReviews() + "</posReviews>"); sb.append("<negReviews>" + dish.getNumNegReviews() + "</negReviews>"); String voteString = "LTE0"; if (vote > 0) voteString = "GT0"; else if (vote < 0) voteString = "LT0"; sb.append("<voteString>" + voteString + "</voteString>"); if (tags != null && !tags.isEmpty()) { sb.append("<tagsEmpty>NE</tagsEmpty>"); } else sb.append("<tagsEmpty>E</tagsEmpty>"); sb.append("<Tags>"); for (Tag tag : tags) { sb.append( "<tag><tagName>" + StringEscapeUtils.escapeHtml(tag.getName()) + "</tagName></tag>"); } sb.append("</Tags>"); Key lastReviewKey = TDQueryUtils.getLatestReviewByDish(dish.getKey()); if (null != lastReviewKey) { final Review lastReview = PMF.get().getPersistenceManager().getObjectById(Review.class, lastReviewKey); if (lastReview.getDirection() == Review.POSITIVE_DIRECTION) { sb.append("<lastReviewType>P</lastReviewType>"); } else sb.append("<lastReviewType>N</lastReviewType>"); sb.append( "<lastReview>" + HumanTime.approximately( System.currentTimeMillis() - lastReview.getDateCreated().getTime()) + "</lastReview>"); } else { sb.append("<lastReviewType>E</lastReviewType>"); } sb.append("<numReview>" + dish.getNumReviews() + "</numReview>"); sb.append("</Dish>"); } sb.append("</Dishes>"); sb.append("</DishSearch>"); } else { namesAdded = true; sb.append("<dishMesg>No records found</dishMesg>"); } if (namesAdded) { resp.setContentType("text/xml"); resp.getWriter().write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>" + sb.toString()); } else { resp.setStatus(HttpServletResponse.SC_NO_CONTENT); } }
public class AudioClipService { DatastoreService datastore = DatastoreServiceFactory.getDatastoreService(); BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); MemcacheService syncCache = MemcacheServiceFactory.getMemcacheService(); UserService userService = new UserService(); public List<AudioClipInstance> getOtherUsersAudioClips(String userId) throws BadRequestException { List<AudioClipInstance> audioClipInstanceList; // no need to check for user existance here! if UserId is null, then all audioClips are returned Filter userFilter = new FilterPredicate(TuneInConstants.AUDIO_CLIP_OWNER_ID, FilterOperator.NOT_EQUAL, userId); Query q = new Query(TuneInConstants.AUDIO_CLIP_TYPE).setFilter(userFilter); PreparedQuery pq = datastore.prepare(q); // check mem-cache for the results first String CACHE_KEY = TuneInConstants.OTHERS_WORK_KEY + userId; audioClipInstanceList = (ArrayList<AudioClipInstance>) syncCache.get(CACHE_KEY); if (audioClipInstanceList == null) { audioClipInstanceList = new ArrayList<AudioClipInstance>(); User user; AudioClipInstance audioClipInstance; for (Entity result : pq.asIterable()) { user = userService.getUserById( (String) result.getProperty(TuneInConstants.AUDIO_CLIP_OWNER_ID)); audioClipInstance = new AudioClipInstance( KeyFactory.keyToString(result.getKey()), (String) result.getProperty(TuneInConstants.AUDIO_CLIP_TITLE), user, (String) result.getProperty(TuneInConstants.AUDIO_CLIP_AUDIO_ID), (String) result.getProperty(TuneInConstants.AUDIO_CLIP_IMAGE_ID), (Date) result.getProperty(TuneInConstants.AUDIO_CLIP_DATE)); audioClipInstanceList.add(audioClipInstance); } syncCache.put(CACHE_KEY, audioClipInstanceList, Expiration.byDeltaSeconds(300)); } return audioClipInstanceList; } public AudioClip getAudioClipById(String id) throws BadRequestException { AudioClip audioClip; try { Key audio_key = KeyFactory.stringToKey(id); Entity result = datastore.get(audio_key); audioClip = new AudioClip( id, (String) result.getProperty(TuneInConstants.AUDIO_CLIP_TITLE), (String) result.getProperty(TuneInConstants.AUDIO_CLIP_OWNER_ID), (String) result.getProperty(TuneInConstants.AUDIO_CLIP_AUDIO_ID), (String) result.getProperty(TuneInConstants.AUDIO_CLIP_IMAGE_ID), (Date) result.getProperty(TuneInConstants.AUDIO_CLIP_DATE)); return audioClip; } catch (Exception e) { throw new BadRequestException(); } } public List<AudioClip> getAudioClipsByUser(String userId) throws BadRequestException { List<AudioClip> audioClipList = new ArrayList<AudioClip>(); // verify userId validateUserExistance(userId); // throws bad request exception of user doesn't exist Filter userFilter = new FilterPredicate(TuneInConstants.AUDIO_CLIP_OWNER_ID, FilterOperator.EQUAL, userId); Query q = new Query(TuneInConstants.AUDIO_CLIP_TYPE) .setFilter(userFilter) .addSort(TuneInConstants.AUDIO_CLIP_DATE, SortDirection.ASCENDING); PreparedQuery pq = datastore.prepare(q); AudioClip audioClip; for (Entity result : pq.asIterable()) { audioClip = new AudioClip( KeyFactory.keyToString(result.getKey()), (String) result.getProperty(TuneInConstants.AUDIO_CLIP_TITLE), (String) result.getProperty(TuneInConstants.AUDIO_CLIP_OWNER_ID), (String) result.getProperty(TuneInConstants.AUDIO_CLIP_AUDIO_ID), (String) result.getProperty(TuneInConstants.AUDIO_CLIP_IMAGE_ID), (Date) result.getProperty(TuneInConstants.AUDIO_CLIP_DATE)); audioClipList.add(audioClip); } return audioClipList; } public String newAudioClip(String userId, String title, String audio, String image) throws BadRequestException { // validate existence of the user validateUserExistance(userId); // throws bad request exception of user doesn't exist Entity audioClip = new Entity(TuneInConstants.AUDIO_CLIP_TYPE); audioClip.setProperty(TuneInConstants.AUDIO_CLIP_TITLE, title); audioClip.setProperty(TuneInConstants.AUDIO_CLIP_AUDIO_ID, audio); audioClip.setProperty(TuneInConstants.AUDIO_CLIP_IMAGE_ID, image); audioClip.setProperty(TuneInConstants.AUDIO_CLIP_OWNER_ID, userId); audioClip.setProperty(TuneInConstants.AUDIO_CLIP_DATE, new Date()); datastore.put(audioClip); return KeyFactory.keyToString(audioClip.getKey()); } public void deleteAudioClip(String audioClipId) throws BadRequestException { AudioClip audioClip = getAudioClipById(audioClipId); datastore.delete(KeyFactory.stringToKey(audioClipId)); // task queue to delete the associated audio and image blobs Queue queue = QueueFactory.getDefaultQueue(); queue.add( TaskOptions.Builder.withUrl("/rest/users/" + audioClip.getOwnerId() + "/audioClips/audio") .method(TaskOptions.Method.DELETE) .param("blobkey", audioClip.getAudioId())); queue.add( TaskOptions.Builder.withUrl("/rest/users/" + audioClip.getOwnerId() + "/audioClips/image") .method(TaskOptions.Method.DELETE) .param("blobkey", audioClip.getImageId())); } public void deleteBlob(String blobkey) { BlobKey blob_key = new BlobKey(blobkey); blobstoreService.delete(blob_key); } // memcache only endpoints public List<AudioClip> getAudioClipInMemcache() throws BadRequestException { ArrayList<AudioClip> audioClipList = (ArrayList<AudioClip>) syncCache.get(TuneInConstants.ALL_AUDIO_CLIPS); return audioClipList; } public String newAudioClipInMemcache(String ownerId, AudioClip audioClip) throws BadRequestException { validateUserExistance(ownerId); ArrayList<AudioClip> audioCLipList = (ArrayList<AudioClip>) syncCache.get(TuneInConstants.ALL_AUDIO_CLIPS); if (audioCLipList == null) { audioCLipList = new ArrayList<AudioClip>(); } audioCLipList.add(audioClip); syncCache.put(TuneInConstants.ALL_AUDIO_CLIPS, audioCLipList, Expiration.byDeltaSeconds(60)); return audioClip.getKeyname(); } private void validateUserExistance(String userId) throws BadRequestException { // validate existence of the user userService.getUserById(userId); // throws bad request exception of user doesn't exist } }
private static void throwBadRequest(BlobKey blobKey, String s) throws IOException { BlobstoreServiceFactory.getBlobstoreService().delete(blobKey); throw new IllegalArgumentException(s); }
public static void serveImage(ImageRef ref, HttpServletResponse response) throws IOException { BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); blobstoreService.serve(getBlobkKey(ref), response); }
public static String getUploadUrl(ImageRef ref) { BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService(); return blobstoreService.createUploadUrl( "/backend/image-post-upload?ref=" + BaseEncoding.base64().encode(ref.toByteArray()), UploadOptions.Builder.withGoogleStorageBucketName(getBucket())); }