Package se.rupy.content

Source Code of se.rupy.content.Upload$Item

package se.rupy.content;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;

import javax.imageio.ImageIO;

import se.rupy.http.Deploy;
import se.rupy.http.Event;
import se.rupy.http.Input;
import se.rupy.http.Output;
import se.rupy.http.Query;
import se.rupy.sprout.Data;
import se.rupy.sprout.Node;
import se.rupy.sprout.Sprout;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

/*
* This service only supports one file at the time.
*/
public class Upload extends Sprout {
  private static int SIZE = 1024;

  public int index() { return 2; }
  public String path() { return "/upload:/picture"; }
  public void filter(Event event) throws Event, Exception {
    if(event.query().method() == Query.POST) {
      if(event.query().path().equals("/picture")) {
        // Because this is called from hidden iframe, we won't see the error stacktrace!
        try {
          Item item = new Item();
          item.path = "file";
          item = save(event, item);

          String path = frame(item);
          Output out = event.output();

          out.println("<script>");
          out.println("  var doc = window.top.document;");
          out.println("  doc.user.picture.value = '" + path + "';");
          out.println("  doc.picture.src = '" + path + "';");
          out.println("</script>");
        }
        catch(Exception e) {
          e.printStackTrace();
          throw e;
        }
      }

      if(event.query().path().equals("/upload")) {
        File file = new File();
        Item item = new Item();
        item.path = "file";
        item = save(event, item);

        Node article = article(event, file, item);
        Sprout.redirect(event, "/");
        //Sprout.redirect(event, "/edit?id=" + article.getId());
      }
    }

    //Sprout.redirect(event, "/");
  }

  static String frame(Item item) throws IOException {
    BufferedImage image = ImageIO.read(item.file);

    int width = image.getWidth();
    int height = image.getHeight();

    if(width > height) {
      image = image.getSubimage((width - height) / 2, 0, height, height);
    }

    if(width < height) {
      image = image.getSubimage(0, (height - width) / 2, width, width);
    }

    String name = item.name.substring(0, item.name.indexOf('.'));
    String path = item.path + "/" + name + ".jpeg";

    Image tiny = image.getScaledInstance(50, 50, Image.SCALE_AREA_AVERAGING);
    save(tiny, new java.io.File(Sprout.ROOT + "/" + path));
    item.file.delete();

    return path;
  }

  static Node article(Event event, Node file, Item item) throws Exception {
    Object key = event.session().get("key");
    Article article = Article.get(key);
    String name = File.name(item.name);
    Node old = article.child(FILE, FILE_NAME, name);

    if(old != null) {
      file = old;
      file.setDate(System.currentTimeMillis());
      Article.invalidate(article);
    }

    file.add(FILE_NAME, name);

    if(old == null) {
      article.add(file);
    }
    else {
      file.update();
    }
   
    boolean delete = false;
   
    if(item.name.endsWith(".jpeg") || item.name.endsWith(".jpg") || item.name.endsWith(".bmp")) {
      resize(item, file, 200);
      file.add(File.type("IMAGE"));
      delete = true;
    }
    else if(item.name.endsWith(".avi") || item.name.endsWith(".mov") || item.name.endsWith(".wmv") || item.name.endsWith(".mp4") || item.name.endsWith(".mkv")) {
      video(item, file);
      file.add(File.type("VIDEO"));
      delete = true;
    }
    else if(item.name.endsWith(".mp3") || item.name.endsWith(".wav")) {
      if(item.name.endsWith(".wav")) {
        audio(item, file);
      }
      else {
        File.copy(Sprout.ROOT + "/file/" + item.name, Sprout.ROOT + "/file" + file.path(), name + ".mp3");
      }
      file.add(File.type("AUDIO"));
      delete = true;
    }

    if(delete) {
      File.delete(item.file);
    }
    else {
      File.copy(Sprout.ROOT + "/file/" + item.name, Sprout.ROOT + "/file" + file.path(), name);
    }

    Article.cache3.remove(key);

    return article;
  }

  static void resize(Item item, Node file, int width) throws IOException {
    BufferedImage image = ImageIO.read(item.file);
    String name = item.name.substring(0, item.name.indexOf('.'));

    File.path(Sprout.ROOT + "/file" + file.path());
   
    Image small = image.getScaledInstance(width, -1, Image.SCALE_AREA_AVERAGING);
    save(small, new java.io.File(Sprout.ROOT + "/file" + file.path() + "/" + name + "-" + width + ".jpeg"));
   
    Image big = image.getScaledInstance(width * 2, -1, Image.SCALE_AREA_AVERAGING);
    save(big, new java.io.File(Sprout.ROOT + "/file" + file.path() + "/" + name + "-" + width * 2 + ".jpeg"));
  }

  static void save(Image small, java.io.File file) throws IOException {
    int width = small.getWidth(null);
    int height = small.getHeight(null);
   
    BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
    Graphics g = image.createGraphics();
    g.setColor(Color.WHITE);
    g.fillRect(0, 0, width, height);
    g.drawImage(small, 0, 0, null);
    g.dispose();

    FileOutputStream out = new FileOutputStream(file);
    JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
    JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
    param.setQuality(1, true);
    encoder.setJPEGEncodeParam(param);
    encoder.encode(image);
    out.flush();
    out.close();
  }

  static void video(Item item, Node file) {
    String name = item.name.substring(0, item.name.indexOf('.'));
    try {
      String line;
      File.path(Sprout.ROOT + "/file" + file.path());
      String path = Sprout.ROOT + "/" + item.path + "/";
      String to = Sprout.ROOT + "/file" + file.path() + "/" + name + ".flv";
      File.delete(to);
      Process p = Runtime.getRuntime().exec("ffmpeg -i " + path + item.name + " -deinterlace -y -b 1024k -ac 2 -ar 22050 -s 320x240 " + to);
      BufferedReader input = new BufferedReader(new InputStreamReader(p.getErrorStream()));
      while ((line = input.readLine()) != null) {
        System.out.println(line);
      }
      input.close();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  static void audio(Item item, Node file) {
    String name = item.name.substring(0, item.name.indexOf('.'));
    try {
      String line;
      File.path(Sprout.ROOT + "/file" + file.path());
      String path = Sprout.ROOT + "/" + item.path + "/";
      String to = Sprout.ROOT + "/file" + file.path() + "/" + name + ".mp3";
      File.delete(to);
      Process p = Runtime.getRuntime().exec("ffmpeg -i " + path + item.name + " " + to);
      BufferedReader input = new BufferedReader(new InputStreamReader(p.getErrorStream()));
      while ((line = input.readLine()) != null) {
        System.out.println(line);
      }
      input.close();
    }
    catch(Exception e) {
      e.printStackTrace();
    }
  }

  public static Item save(Event event, Item item) throws Event, IOException {
    String type = event.query().header("content-type");
    String boundary = "--" + unquote(type.substring(type.indexOf("boundary=") + 9));

    Input in = event.input();
    String line = in.line();

    while(line != null) {
      /*
       * find boundary
       */

      if(line.equals(boundary + "--")) {
        Sprout.redirect(event, "/");
      }

      if(line.equals(boundary)) {
        line = in.line();

        /*
         * read headers; parse filename and content-type
         */

        while(line != null && !line.equals("")) {
          int colon = line.indexOf(":");

          if (colon > -1) {
            String name = line.substring(0, colon).toLowerCase();
            String value = line.substring(colon + 1).trim();

            if(name.equals("content-disposition")) {
              item.name = unpath(unquote(value.substring(value.indexOf("filename=") + 9).trim()));
            }

            if(name.equals("content-type")) {
              item.type = value;
            }
          }

          line = in.line();
        }

        if(item.name == null || item.name.length() == 0) {
          Sprout.redirect(event, "/");
        }

        /*
         * create path and file
         */

        java.io.File path = new java.io.File(Sprout.ROOT + "/" + item.path);

        if(!path.exists()) {
          path.mkdirs();
        }

        item.file = new java.io.File(Sprout.ROOT + "/" + item.path + "/" + item.name);
        FileOutputStream out = new FileOutputStream(item.file);

        /*
         * stream data
         */

        Boundary bound = new Boundary();
        bound.value = ("\r\n" + boundary).getBytes();

        byte[] data = new byte[SIZE];
        int read = in.read(data);

        while(read > -1) {
          try {
            out.write(data, 0, bound.find(read, data, out));
          }
          catch(Boundary.EOB eob) {
            out.write(data, 0, eob.index);
            out.flush();
            out.close();

            // only handles one file for now,
            // need to rewind the stream for
            // multiple files.
            return item;
          }

          read = in.read(data);
        }

        throw new IOException("Boundary not found. (trailing)");
      }

      line = in.line();
    }

    throw new IOException("Boundary not found. (initing)");
  }

  static String unquote(String value) {
    int index = value.lastIndexOf("\"");

    if(index > -1) {
      return value.substring(1, index);
    }

    return value;
  }

  static String unpath(String value) {
    int index = Math.max(value.lastIndexOf('/'), value.lastIndexOf('\\'));

    if(index > -1) {
      return value.substring(index + 1);
    }

    return value;
  }

  public static class Item {
    String name;
    String path;
    String type;
    java.io.File file;

    public String toString() {
      return name + " " + path + " " + type;
    }
  }

  /*
   * The multipart protocol was poorly designed, so we have to check
   * for the boundary for every byte and handle things if the boundary
   * is between buffers.
   *
   * TODO: An alternative way is to write everything from headers onwards
   * to a file and then search for the boundary starting at the end of the
   * file, and crop the boundary.
   */
  public static class Boundary {
    byte[] value;
    int index; // remember boundary index between finds

    int find(int read, byte[] data, OutputStream out) throws EOB, IOException {
      int wrap = index;

      for(int i = 0; i < read; i++) {
        if(data[i] == value[index]) {     // maybe boundary
          if(index == value.length - 1) { // boundary
            int start = i - value.length + 1;
            throw new EOB(start > -1 ? start : 0);
          }
          index++;
        }
        else {          // not boundary
          if(wrap > 0) { // write non-boundary from last find
            out.write(value, 0, wrap);
            wrap = 0;
          }
          index = 0;
        }
      }

      return read - index;
    }

    public static class EOB extends Throwable {
      int index;

      public EOB(int index) {
        this.index = index;
      }
    }
  }
}
TOP

Related Classes of se.rupy.content.Upload$Item

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.