view src/nabble/view/web/forum/Thumbnail.java @ 0:7ecd1a4ef557

add content
author Franklin Schmidt <fschmidt@gmail.com>
date Thu, 21 Mar 2019 19:15:52 -0600
parents
children
line wrap: on
line source

package nabble.view.web.forum;

import fschmidt.util.java.ImageUtils;
import fschmidt.util.java.IoUtils;
import fschmidt.util.servlet.AuthorizingServlet;
import fschmidt.util.servlet.CanonicalUrl;
import fschmidt.util.servlet.JtpContext;
import nabble.model.FileUpload;
import nabble.model.Message;
import nabble.model.Node;
import nabble.model.Site;
import nabble.model.SystemProperties;
import nabble.view.lib.Cache;
import nabble.view.lib.Jtp;
import nabble.view.lib.UrlMappable;
import org.apache.commons.fileupload.FileItem;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class Thumbnail extends HttpServlet implements UrlMappable, AuthorizingServlet, CanonicalUrl {

	private static final String NABBLE_IMAGE_CODE = "<nabble_img src=\"";
	private static final Pattern YOUTUBE_PATTERN = Pattern.compile("[ ]src[ ]*=[ ]*\"(https?:)?//www\\.youtube(-nocookie)?\\.com/(v|embed)/([^&?\"]*)(.*)\"");
	private static final Pattern EXTERNAL_IMG_PATTERN = Pattern.compile("<img(\\s|\\w|=|\"|')+src[ ]*=[ ]*[\"|'](\\S+)[\"|']");

	private static final Pattern URL_PATTERN = Pattern.compile("/file/thumb/n(\\d+)(/(.+))?$");

	public static String url(Node node, String fileName) {
		return node.getSite().getBaseUrl() + path(node,fileName);
	}

	public static String path(Node node, String fileName) {
		return "/file/thumb/n" + node.getId() + (fileName == null? "" : '/' + fileName);
	}

	public String getCanonicalUrl(HttpServletRequest request) {
		Site site = Jtp.getSite(request);
		if( site == null )
			return null;
		return url(site.getNode(Long.parseLong(request.getParameter("node"))), request.getParameter("filename"));
	}

	public Map<String,String[]> getParameterMapFromUrl(HttpServletRequest request,String mappedUrl) {
		Matcher m = URL_PATTERN.matcher(mappedUrl);
		if (!m.find())
			throw new RuntimeException();
		Map<String,String[]> params = new HashMap<String,String[]>();
		String nodeIdS = m.group(1);
		params.put("node", new String[]{nodeIdS});
		String fileName = m.group(2);
		if (fileName != null && fileName.length() > 1)
			params.put("filename", new String[]{fileName.substring(1)});
		return params;
	}

	public Pattern getUrlPattern() {
		return URL_PATTERN;
	}

	public String getAuthorizationKey(HttpServletRequest request) throws ServletException {
		return Jtp.getReadAuthorizationKey( Jtp.getSiteNotNull(request).getNode(Jtp.getLong(request,"node")));
	}

	public boolean authorize(String key,HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		return Jtp.authorizeForRead(key,request,response);
	}

	protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		Node node = Jtp.getSiteNotNull(request).getNode(Jtp.getLong(request, "node"));
		if (node == null)
			return;

		JtpContext jtpContext = (JtpContext)getServletContext().getAttribute(JtpContext.attrName);
		jtpContext.setEtag(request,response,Cache.nodeChangeEvent(node));

		String fileName = request.getParameter("filename");
		BufferedImage img  = getImage(node, fileName, response);
		if (img == null) {
			response.sendError(HttpServletResponse.SC_NOT_FOUND);
			return;
		}

		InputStream in = null;
		try {
			img = ImageUtils.getThumbnail(img, 140, 100);
			in = ImageUtils.asInputStream(img, "jpg");
			IoUtils.copyAll(in, response.getOutputStream());
		} finally {
			if (in != null)
				in.close();
		}
	}

	private BufferedImage getImage(Node node, String fileName, HttpServletResponse response)
		throws ServletException
	{
		if (fileName == null) {
			try {
				String message = node.getMessage().getRaw();
				Matcher m = EXTERNAL_IMG_PATTERN.matcher(message);
				if (m.find()) {
					String imgUrl = m.group(2);
					FileItem fi = new FileUpload.UrlFileItem(new URL(imgUrl));
					response.setContentType(FileDownload.getMimeByExtension(imgUrl));
					return ImageUtils.getImage(fi.getInputStream());
				}
			} catch(IOException e) {
				throw new ServletException("getImage failed",e);
			}
		} else {
			try {
				Message.Source src = Message.SourceType.getType('n').getSource(node.getSite(),node.getId());
				InputStream in = FileUpload.getFileContent(src,fileName);
				if (in != null) {
					response.setContentType(FileDownload.getMimeByExtension(fileName));
					try {
						return ImageUtils.getImage(in);
					} finally {
						in.close();
					}
				}
			} catch(IOException e) {
				throw new RuntimeException("getImage failed",e);
			}
		}
		return null;
	}

	public static String getThumbnailFile(Node node) {
		String src = null;

		String message = node.getMessage().getRaw();
		int posStart = message.indexOf(NABBLE_IMAGE_CODE);
		if (posStart >= 0) {
			int srcStart = posStart + NABBLE_IMAGE_CODE.length();
			int posEnd = message.indexOf("\"", srcStart);
			src = "/file/thumb/n" + node.getId() + '/' + message.substring(srcStart, posEnd);
		}
		if (src == null) {
			// Let's check for youtube videos
			Matcher m = YOUTUBE_PATTERN.matcher(message);
			if(m.find()) {
				String code = m.group(4);
				src = "http://i1.ytimg.com/vi/" + code + "/default.jpg";
			}
		}
		if (src == null) {
			Matcher m = EXTERNAL_IMG_PATTERN.matcher(message);
			if(m.find()) {
				return "/file/thumb/n" + node.getId();
			}
		}
		return src;
	}
}