diff 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 diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/nabble/view/web/forum/Thumbnail.java	Thu Mar 21 19:15:52 2019 -0600
@@ -0,0 +1,167 @@
+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;
+	}
+}