Mercurial Hosting > nabble
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; + } +}