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 sendMail(
     HttpServletRequest request, BlogAuthor blogAuthor, Entity blog, Settings settings)
     throws IOException {
   if (settings.dontSendEmail()) {
     return;
   }
   try {
     String digest = DS.getBlogDigest(blog);
     MailService mailService = MailServiceFactory.getMailService();
     Message reply = new Message();
     reply.setSender(blogAuthor.toString());
     Email sender = (Email) blog.getProperty(SenderProperty);
     reply.setTo(sender.getEmail());
     String subject = (String) blog.getProperty(SubjectProperty);
     reply.setSubject("Blog: " + subject + " received");
     StringBuilder sb = new StringBuilder();
     URI reqUri = new URI(request.getScheme(), NamespaceManager.get(), "", "");
     if (!settings.isPublishImmediately()) {
       sb.append("<div>");
       sb.append(
           "<p>Blog is not yet published because it was sent from untrusted email address "
               + sender.getEmail()
               + ". </p>");
       URI publishUri =
           reqUri.resolve(
               "/blog?action=publish&blog="
                   + KeyFactory.keyToString(blog.getKey())
                   + "&auth="
                   + digest);
       sb.append("<a href=\"" + publishUri.toASCIIString() + "\">Publish Blog</a>");
       sb.append("</div>");
     }
     sb.append("<div>");
     sb.append("<p>If blog is not ok, you can delete and then resend it.</p>");
     URI deleteUri =
         reqUri.resolve(
             "/blog?action=remove&blog="
                 + KeyFactory.keyToString(blog.getKey())
                 + "&auth="
                 + digest);
     sb.append("<a href=\"" + deleteUri.toASCIIString() + "\">Delete Blog</a>");
     sb.append("</div>");
     reply.setHtmlBody(sb.toString());
     mailService.send(reply);
   } catch (URISyntaxException ex) {
     throw new IOException(ex);
   }
 }
 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();
     }
   }
 }
Beispiel #4
0
  public GeoData(DS ds) {
    Iterable<Entity> tracksIterable = ds.fetchTracks();
    Iterable<Entity> imageLocationsIterable = ds.fetchImageLocations();
    Iterable<Entity> blogLocationsIterable = ds.fetchBlogLocations();

    boxList = new HashMapList<>();
    Date lastBegin = null;
    for (Entity track : tracksIterable) {
      BoundingBox bbTrack = new BoundingBox(track);
      for (Entity trackSeq : ds.fetchTrackSeqs(track.getKey())) {
        BoundingBox bbTrackSeq = new BoundingBox(trackSeq);
        boxList.add(bbTrack, new Pair<BoundingBox, Key>(bbTrackSeq, trackSeq.getKey()));
        Date begin = (Date) trackSeq.getProperty(BeginProperty);
        if (lastBegin == null || lastBegin.before(begin)) {
          lastBegin = begin;
        }
      }
    }
    Iterable<Entity> placemarksIterable;
    if (lastBegin != null) {
      placemarksIterable = ds.fetchPlacemarks(lastBegin);
    } else {
      placemarksIterable = ds.fetchPlacemarks();
    }
    firstPlacemarkKey = null;
    placemarkBoundingBox = new BoundingBox();
    for (Entity placemark : placemarksIterable) {
      if (firstPlacemarkKey == null) {
        firstPlacemarkKey = placemark.getKey();
      }
      GeoPt location = (GeoPt) placemark.getProperty(LocationProperty);
      placemarkBoundingBox.add(location);
    }
    locationList = new ArrayList<>();
    for (Entity metadata : imageLocationsIterable) {
      GeoPt location = (GeoPt) metadata.getProperty(LocationProperty);
      if (location != null) {
        locationList.add(new Pair<>(location, metadata.getKey()));
      }
    }
    for (Entity blog : blogLocationsIterable) {
      GeoPt location = (GeoPt) blog.getProperty(LocationProperty);
      if (location != null) {
        locationList.add(new Pair<>(location, blog.getKey()));
      }
    }
  }
 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");
      }
    }
  }