private boolean handleSpot(MimeMessage message) throws IOException, MessagingException { String spotTime = getSpotHeader(message, "X-SPOT-Time"); if (spotTime != null) { String spotLatitude = getSpotHeader(message, "X-SPOT-Latitude"); String spotLongitude = getSpotHeader(message, "X-SPOT-Longitude"); String spotMessenger = getSpotHeader(message, "X-SPOT-Messenger"); String spotType = getSpotHeader(message, "X-SPOT-Type"); Date time = new Date(Long.parseLong(spotTime) * 1000); GeoPt geoPt = new GeoPt(Float.parseFloat(spotLatitude), Float.parseFloat(spotLongitude)); DS ds = DS.get(); ds.addPlacemark(time, geoPt, spotMessenger, spotType); return true; } return false; }
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(); } } }
private Collection<Future<HTTPResponse>> handleBodyPart( HttpServletRequest request, Entity blog, BodyPart bodyPart, final Settings settings) throws MessagingException, IOException { ImagesService imagesService = ImagesServiceFactory.getImagesService(); DS ds = DS.get(); Collection<Future<HTTPResponse>> futures = new ArrayList<>(); String contentType = bodyPart.getContentType(); log(contentType); Object content = bodyPart.getContent(); if (content instanceof InputStream) { String filename = bodyPart.getFileName(); byte[] bytes = getBytes(bodyPart); String digestString = DS.getDigest(bytes); Entity metadata = createMetadata(digestString, filename, contentType, bytes); if (contentType.startsWith("image/")) { int oWidth; int oHeight; int wWidth; int wHeight; Image image = ImagesServiceFactory.makeImage(bytes); if (settings.isFixPic()) { Transform makeImFeelingLucky = ImagesServiceFactory.makeImFeelingLucky(); image = imagesService.applyTransform(makeImFeelingLucky, image); } oWidth = image.getWidth(); oHeight = image.getHeight(); if (image.getHeight() > settings.getPicMaxHeight() || image.getWidth() > settings.getPicMaxWidth()) { log( "shrinking [" + image.getHeight() + ", " + image.getWidth() + "] > [" + settings.getPicMaxHeight() + ", " + settings.getPicMaxWidth() + "]"); Transform makeResize = ImagesServiceFactory.makeResize( settings.getPicMaxHeight(), settings.getPicMaxWidth()); Image shrinken = imagesService.applyTransform(makeResize, image); wWidth = shrinken.getWidth(); wHeight = shrinken.getHeight(); Future<HTTPResponse> res = postBlobs( filename, contentType, digestString, shrinken.getImageData(), WebSizeProperty, request, wWidth, wHeight); futures.add(res); } else { wWidth = image.getWidth(); wHeight = image.getHeight(); Future<HTTPResponse> res = postBlobs( filename, contentType, digestString, bytes, WebSizeProperty, request, wWidth, wHeight); futures.add(res); } Future<HTTPResponse> res = postBlobs( filename, contentType, digestString, bytes, OriginalSizeProperty, request, oWidth, oHeight); futures.add(res); String[] cids = bodyPart.getHeader("Content-ID"); if (cids != null && cids.length > 0) { String alt = (String) metadata.getProperty(UserCommentProperty); if (alt == null) { alt = ""; } replaceBlogRef(blog, cids[0], digestString, wWidth, wHeight, alt); } } if (contentType.startsWith("application/vnd.google-earth.kml+xml") || filename.endsWith(".kml")) { try { InputStream is = (InputStream) content; KML kml = new KML(is); PlacemarkUpdater pu = new PlacemarkUpdater(ds, kml, LocatorLevel.Field); pu.visit(kml, null); } catch (JAXBException ex) { log("reading kml failed", ex); } } if (contentType.startsWith("application/vnd.google-earth.kmz") || filename.endsWith(".kmz")) { try { InputStream is = (InputStream) content; KMZ kmz = new KMZ(is); PlacemarkUpdater pu = new PlacemarkUpdater(ds, kmz, LocatorLevel.Field); pu.visit(kmz, null); } catch (JAXBException ex) { log("reading kmz failed", ex); } } if (filename.endsWith(".gpx")) { try { InputStream is = (InputStream) content; final GPX gpx = new GPX(is); final OpenCPNTrackHandler handler = new OpenCPNTrackHandler(ds); RunInNamespace rin = new RunInNamespace() { @Override protected Object run() { gpx.browse( settings.getTrackBearingTolerance(), settings.getTrackMinimumDistance(), settings.getTrackMaxSpeed(), handler); return null; } }; rin.doIt(null, settings.isCommonPlacemarks()); } catch (JAXBException ex) { log("reading gpx failed", ex); } } if (filename.endsWith(".trc")) { InputStream is = (InputStream) content; final TrackInput trackInput = new TrackInput(is); final CompressedTrackHandler cth = new CompressedTrackHandler(ds); RunInNamespace rin = new RunInNamespace() { @Override protected Object run() { try { cth.handle(trackInput); } catch (IOException ex) { log(ex.getMessage(), ex); } return null; } }; rin.doIt(null, settings.isCommonPlacemarks()); } if (contentType.startsWith("application/X-jsr179-location-nmea") || filename.endsWith(".nmea")) { log("NMEA not yet supported"); } } return futures; }
private void handleMail( HttpServletRequest request, HttpServletResponse response, BlogAuthor blogAuthor) throws IOException, ServletException, EntityNotFoundException, MessagingException, HttpException { DS ds = DS.get(); Properties props = new Properties(); Session session = Session.getDefaultInstance(props, null); MimeMessage message = new MimeMessage(session, request.getInputStream()); String messageId = getMessageId(message); String contentType = message.getContentType(); if (messageId == null) { log("messageID missing"); response.sendError(HttpServletResponse.SC_BAD_REQUEST); return; } log("Message-ID=" + messageId); // TODO authorization if (handleSpot(message)) { return; } InternetAddress sender = (InternetAddress) message.getSender(); log("sender=" + sender); if (sender == null) { Address[] from = message.getFrom(); if (from != null && from.length != 0) { sender = (InternetAddress) from[0]; } } if (sender == null) { log("Sender missing"); response.sendError(HttpServletResponse.SC_BAD_REQUEST); return; } Email senderEmail = new Email(sender.getAddress()); Settings settings = ds.getSettingsFor(senderEmail); if (settings == null) { log(senderEmail.getEmail() + " not allowed to send blogs"); response.sendError(HttpServletResponse.SC_FORBIDDEN); return; } String[] ripperDate = message.getHeader(BlogRipper + "Date"); boolean ripping = ripperDate != null && ripperDate.length > 0; Object content = message.getContent(); if (content instanceof Multipart) { Multipart multipart = (Multipart) message.getContent(); List<BodyPart> bodyPartList = findParts(multipart); try { Entity blog = null; String htmlBody = getHtmlBody(bodyPartList); if (htmlBody != null && htmlBody.length() > 10) { boolean publishImmediately = settings.isPublishImmediately(); blog = updateBlog(messageId, message, htmlBody, publishImmediately, senderEmail); if (!ripping) { if (blog != null) { sendMail(request, blogAuthor, blog, settings); } } else { log("not sending email because ripping"); } } else { log("no html body"); } List<Future<HTTPResponse>> futureList = new ArrayList<Future<HTTPResponse>>(); for (BodyPart bodyPart : bodyPartList) { Collection<Future<HTTPResponse>> futures = handleBodyPart(request, blog, bodyPart, settings); if (futures != null) { futureList.addAll(futures); } } long remainingMillis = ApiProxy.getCurrentEnvironment().getRemainingMillis(); log("remainingMillis=" + remainingMillis); for (Future<HTTPResponse> res : futureList) { try { HTTPResponse hr = res.get(); log("code=" + hr.getResponseCode()); if (hr.getResponseCode() != HttpServletResponse.SC_OK) { throw new ServletException("blob upload failed code=" + hr.getResponseCode()); } } catch (InterruptedException ex) { throw new IOException(ex); } catch (ExecutionException ex) { throw new IOException(ex); } } } catch (MessagingException ex) { throw new IOException(ex); } } else { if (content instanceof String) { String bodyPart = (String) content; if (contentType.startsWith("text/plain")) { bodyPart = textPlainToHtml(bodyPart); } boolean publishImmediately = settings.isPublishImmediately(); Entity blog = updateBlog(messageId, message, bodyPart, publishImmediately, senderEmail); if (blog != null) { sendMail(request, blogAuthor, blog, settings); } } else { log("body not MultiPart of String"); } } }