• Icon: Improvement Improvement
    • Resolution: Fixed
    • Icon: Major Major
    • 3.5
    • None
    • None
    • None

      We should save paste images.
      They are provided in the html code as binary :

      <p><img class="simple" alt="" src="data:image/png;base64,iVBORw0KGgo..."/></p>
      

      It would be easy to store them in the UploadedDataHTMLEditionHandler because we sometimes fetch distant images. By adding :

      else if attrs.getValue("src").startsWith("data:image/")
      {
         ...
      }
      

          [CMS-4075] Save paste images

          Works fine (in FF) (using another Base64 class)

          Raphaël Franchet added a comment - Works fine (in FF) (using another Base64 class)

          Here a non working patch... everything is ok but the final image does not work

          Index: main/plugin-cms/src/org/ametys/cms/transformation/htmledition/UploadedDataHTMLEditionHandler.java
          ===================================================================
          --- main/plugin-cms/src/org/ametys/cms/transformation/htmledition/UploadedDataHTMLEditionHandler.java	(revision 18789)
          +++ main/plugin-cms/src/org/ametys/cms/transformation/htmledition/UploadedDataHTMLEditionHandler.java	(working copy)
          @@ -19,6 +19,7 @@
           import java.io.ByteArrayInputStream;
           import java.io.IOException;
           import java.io.InputStream;
          +import java.io.UnsupportedEncodingException;
           import java.net.HttpURLConnection;
           import java.net.URI;
           import java.net.URL;
          @@ -42,6 +43,7 @@
           import org.apache.commons.io.output.ByteArrayOutputStream;
           import org.apache.excalibur.source.Source;
           import org.apache.excalibur.source.SourceResolver;
          +import org.apache.jackrabbit.util.Base64;
           import org.xml.sax.Attributes;
           import org.xml.sax.SAXException;
           
          @@ -135,116 +137,145 @@
                           // image is copied from elsewhere, fetch it in the content
                           String src = attrs.getValue("src");
                           String ametys_src = attrs.getValue("ametys_src");
          -                
          -                int j = src.lastIndexOf('/');
          -                int k = src.indexOf('?', j);
          -                String initialFileName;
          -                
          -                if (k == -1)
          -                {
          -                    initialFileName = src.substring(j + 1);
          -                }
          -                else
          -                {
          -                    initialFileName = src.substring(j + 1, k);
          -                }
          -                
          -                // FIXME CMS-3090 A uploaded image can not contain '_max', replace it by '_Max'
          -                initialFileName = initialFileName.replaceAll("_max", "_Max");
          -                
          +
          +                // The final filename
          +                String fileName = null;
                           // The new attributes, will be filled with image width and height.
                           AttributesImpl newAttrs = new AttributesImpl();
                           
          -                InputStream is = null;
          -                String fileName = null;
          -                
          -                if (src.startsWith("/"))
          +                final String INLINE_IMAGE_MARKER = "data:image/png;base64,";
          +                int inlineImageMarkerIndex = src.indexOf(INLINE_IMAGE_MARKER);
          +                if (inlineImageMarkerIndex == 0)
                           {
          -                    // it may be an internal URL
          -                    Request request = ContextHelper.getRequest(_context);
          -                    String contextPath = request.getContextPath();
          -                    Source source = null;
          -                    
          +                    String imageAsBase64 = src.substring(INLINE_IMAGE_MARKER.length());
          +                    String imageAsString = Base64.decode(imageAsBase64);
          +
                               try
                               {
          -                        if (src.startsWith(contextPath))
          -                        {
          -                            // it is an Ametys URL
          -                            // first decode it
          -                            src = new URI(src).getPath();
          -                            
          -                            src = "cocoon:/" + src.substring(contextPath.length());
          -                        }
          -                        else
          -                        {
          -                            StringBuilder sb = _getRequestURI(request);
          -                            
          -                            src = sb.toString() + src;
          -                        }
          +                        byte[] imageAsBytes = imageAsString.getBytes("UTF-8");
          +                        fileName = _storeFile("paste.png", new ByteArrayInputStream(imageAsBytes), null, null);
                                   
          -                        source = _resolver.resolveURI(src);
          -                        is = source.getInputStream();
          -                        
          -                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
          -                        IOUtils.copy(is, bos);
          -                        
          -                        fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null, null);
          -                        
          -                        _addDimensionAttributes(new ByteArrayInputStream(bos.toByteArray()), newAttrs);
          +                        _addDimensionAttributes(new ByteArrayInputStream(imageAsBytes), newAttrs);
                               }
          -                    catch (Exception e)
          +                    catch (UnsupportedEncodingException e)
                               {
                                   // unable to fetch image, do not keep the img tag
                                   _tagToIgnore = true;
          -                        getLogger().warn("Unable to fetch image from URL '" + src + "'. Image is ignored.", e);
          +                        getLogger().warn("Unable to fetch image from inline'. Image is ignored.", e);
                                   return;
                               }
          -                    finally
          +                }
          +                else
          +                {
          +                    
          +                    int j = src.lastIndexOf('/');
          +                    int k = src.indexOf('?', j);
          +                    String initialFileName;
          +                    
          +                    if (k == -1)
          +                    {
          +                        initialFileName = src.substring(j + 1);
          +                    }
          +                    else
                               {
          -                        if (source != null)
          +                        initialFileName = src.substring(j + 1, k);
          +                    }
          +                    
          +                    // FIXME CMS-3090 A uploaded image can not contain '_max', replace it by '_Max'
          +                    initialFileName = initialFileName.replaceAll("_max", "_Max");
          +                    
          +                    if (src.startsWith("/"))
          +                    {
          +                        InputStream is = null;
          +    
          +                        // it may be an internal URL
          +                        Request request = ContextHelper.getRequest(_context);
          +                        String contextPath = request.getContextPath();
          +                        Source source = null;
          +                        
          +                        try
          +                        {
          +                            if (src.startsWith(contextPath))
          +                            {
          +                                // it is an Ametys URL
          +                                // first decode it
          +                                src = new URI(src).getPath();
          +                                
          +                                src = "cocoon:/" + src.substring(contextPath.length());
          +                            }
          +                            else
          +                            {
          +                                StringBuilder sb = _getRequestURI(request);
          +                                
          +                                src = sb.toString() + src;
          +                            }
          +                            
          +                            source = _resolver.resolveURI(src);
          +                            is = source.getInputStream();
          +                            
          +                            ByteArrayOutputStream bos = new ByteArrayOutputStream();
          +                            IOUtils.copy(is, bos);
          +                            
          +                            fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null, null);
          +                            
          +                            _addDimensionAttributes(new ByteArrayInputStream(bos.toByteArray()), newAttrs);
          +                        }
          +                        catch (Exception e)
          +                        {
          +                            // unable to fetch image, do not keep the img tag
          +                            _tagToIgnore = true;
          +                            getLogger().warn("Unable to fetch image from URL '" + src + "'. Image is ignored.", e);
          +                            return;
          +                        }
          +                        finally
                                   {
          -                            _resolver.release(source);
          +                            if (source != null)
          +                            {
          +                                _resolver.release(source);
          +                            }
          +                            IOUtils.closeQuietly(is);
                                   }
          -                        IOUtils.closeQuietly(is);
                               }
          -                }
          -                else if (src.startsWith("http://") || src.startsWith("https://"))
          -                {
          -                    try
          +                    else if (src.startsWith("http://") || src.startsWith("https://"))
                               {
          -                        URL url = new URL(src);
          -                        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
          -                        connection.setConnectTimeout(1000);
          -                        connection.setReadTimeout(2000);
          -                        
          -                        is = connection.getInputStream();
          -                        
          -                        ByteArrayOutputStream bos = new ByteArrayOutputStream();
          -                        IOUtils.copy(is, bos);
          -                        
          -                        fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null, null);
          -                        
          -                        _addDimensionAttributes(new ByteArrayInputStream(bos.toByteArray()), newAttrs);
          +                        InputStream is = null;
          +    
          +                        try
          +                        {
          +                            URL url = new URL(src);
          +                            HttpURLConnection connection = (HttpURLConnection) url.openConnection();
          +                            connection.setConnectTimeout(1000);
          +                            connection.setReadTimeout(2000);
          +                            
          +                            is = connection.getInputStream();
          +                            
          +                            ByteArrayOutputStream bos = new ByteArrayOutputStream();
          +                            IOUtils.copy(is, bos);
          +                            
          +                            fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null, null);
          +                            
          +                            _addDimensionAttributes(new ByteArrayInputStream(bos.toByteArray()), newAttrs);
          +                        }
          +                        catch (Exception e)
          +                        {
          +                            // unable to fetch image, do not keep the img tag
          +                            _tagToIgnore = true;
          +                            getLogger().warn("Unable to fetch image from URL '" + src + "'. Image is ignored.", e);
          +                            return;
          +                        }
          +                        finally
          +                        {
          +                            IOUtils.closeQuietly(is);
          +                        }
                               }
          -                    catch (Exception e)
          +                    else
                               {
          -                        // unable to fetch image, do not keep the img tag
                                   _tagToIgnore = true;
          -                        getLogger().warn("Unable to fetch image from URL '" + src + "'. Image is ignored.", e);
          +                        getLogger().warn("Don't know how to fetch image at '" + src + "'. Image is ignored.");
                                   return;
                               }
          -                    finally
          -                    {
          -                        IOUtils.closeQuietly(is);
          -                    }
          -                }
          -                else
          -                {
          -                    _tagToIgnore = true;
          -                    getLogger().warn("Don't know how to fetch image at '" + src + "'. Image is ignored.");
          -                    return;
                           }
          -                
          +                    
                           _copyAttributes(attrs, newAttrs);
                           
                           newAttrs.addAttribute("", "ametys_src", "ametys_src", "CDATA", ametys_src + ";" + fileName);
          

          Raphaël Franchet added a comment - Here a non working patch... everything is ok but the final image does not work Index: main/plugin-cms/src/org/ametys/cms/transformation/htmledition/UploadedDataHTMLEditionHandler.java =================================================================== --- main/plugin-cms/src/org/ametys/cms/transformation/htmledition/UploadedDataHTMLEditionHandler.java (revision 18789) +++ main/plugin-cms/src/org/ametys/cms/transformation/htmledition/UploadedDataHTMLEditionHandler.java (working copy) @@ -19,6 +19,7 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; + import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; @@ -42,6 +43,7 @@ import org.apache.commons.io.output.ByteArrayOutputStream; import org.apache.excalibur.source.Source; import org.apache.excalibur.source.SourceResolver; + import org.apache.jackrabbit.util.Base64; import org.xml.sax.Attributes; import org.xml.sax.SAXException; @@ -135,116 +137,145 @@ // image is copied from elsewhere, fetch it in the content String src = attrs.getValue( "src" ); String ametys_src = attrs.getValue( "ametys_src" ); - - int j = src.lastIndexOf( '/' ); - int k = src.indexOf( '?' , j); - String initialFileName; - - if (k == -1) - { - initialFileName = src.substring(j + 1); - } - else - { - initialFileName = src.substring(j + 1, k); - } - - // FIXME CMS-3090 A uploaded image can not contain '_max' , replace it by '_Max' - initialFileName = initialFileName.replaceAll( "_max" , "_Max" ); - + + // The final filename + String fileName = null ; // The new attributes, will be filled with image width and height. AttributesImpl newAttrs = new AttributesImpl(); - InputStream is = null ; - String fileName = null ; - - if (src.startsWith( "/" )) + final String INLINE_IMAGE_MARKER = "data:image/png;base64," ; + int inlineImageMarkerIndex = src.indexOf(INLINE_IMAGE_MARKER); + if (inlineImageMarkerIndex == 0) { - // it may be an internal URL - Request request = ContextHelper.getRequest(_context); - String contextPath = request.getContextPath(); - Source source = null ; - + String imageAsBase64 = src.substring(INLINE_IMAGE_MARKER.length()); + String imageAsString = Base64.decode(imageAsBase64); + try { - if (src.startsWith(contextPath)) - { - // it is an Ametys URL - // first decode it - src = new URI(src).getPath(); - - src = "cocoon:/" + src.substring(contextPath.length()); - } - else - { - StringBuilder sb = _getRequestURI(request); - - src = sb.toString() + src; - } + byte [] imageAsBytes = imageAsString.getBytes( "UTF-8" ); + fileName = _storeFile( "paste.png" , new ByteArrayInputStream(imageAsBytes), null , null ); - source = _resolver.resolveURI(src); - is = source.getInputStream(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - IOUtils.copy(is, bos); - - fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null , null ); - - _addDimensionAttributes( new ByteArrayInputStream(bos.toByteArray()), newAttrs); + _addDimensionAttributes( new ByteArrayInputStream(imageAsBytes), newAttrs); } - catch (Exception e) + catch (UnsupportedEncodingException e) { // unable to fetch image, do not keep the img tag _tagToIgnore = true ; - getLogger().warn( "Unable to fetch image from URL '" + src + "' . Image is ignored." , e); + getLogger().warn( "Unable to fetch image from inline'. Image is ignored." , e); return ; } - finally + } + else + { + + int j = src.lastIndexOf( '/' ); + int k = src.indexOf( '?' , j); + String initialFileName; + + if (k == -1) + { + initialFileName = src.substring(j + 1); + } + else { - if (source != null ) + initialFileName = src.substring(j + 1, k); + } + + // FIXME CMS-3090 A uploaded image can not contain '_max' , replace it by '_Max' + initialFileName = initialFileName.replaceAll( "_max" , "_Max" ); + + if (src.startsWith( "/" )) + { + InputStream is = null ; + + // it may be an internal URL + Request request = ContextHelper.getRequest(_context); + String contextPath = request.getContextPath(); + Source source = null ; + + try + { + if (src.startsWith(contextPath)) + { + // it is an Ametys URL + // first decode it + src = new URI(src).getPath(); + + src = "cocoon:/" + src.substring(contextPath.length()); + } + else + { + StringBuilder sb = _getRequestURI(request); + + src = sb.toString() + src; + } + + source = _resolver.resolveURI(src); + is = source.getInputStream(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + IOUtils.copy(is, bos); + + fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null , null ); + + _addDimensionAttributes( new ByteArrayInputStream(bos.toByteArray()), newAttrs); + } + catch (Exception e) + { + // unable to fetch image, do not keep the img tag + _tagToIgnore = true ; + getLogger().warn( "Unable to fetch image from URL '" + src + "' . Image is ignored." , e); + return ; + } + finally { - _resolver.release(source); + if (source != null ) + { + _resolver.release(source); + } + IOUtils.closeQuietly(is); } - IOUtils.closeQuietly(is); } - } - else if (src.startsWith( "http: //" ) || src.startsWith( "https://" )) - { - try + else if (src.startsWith( "http: //" ) || src.startsWith( "https://" )) { - URL url = new URL(src); - HttpURLConnection connection = (HttpURLConnection) url.openConnection(); - connection.setConnectTimeout(1000); - connection.setReadTimeout(2000); - - is = connection.getInputStream(); - - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - IOUtils.copy(is, bos); - - fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null , null ); - - _addDimensionAttributes( new ByteArrayInputStream(bos.toByteArray()), newAttrs); + InputStream is = null ; + + try + { + URL url = new URL(src); + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setConnectTimeout(1000); + connection.setReadTimeout(2000); + + is = connection.getInputStream(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + IOUtils.copy(is, bos); + + fileName = _storeFile(initialFileName, new ByteArrayInputStream(bos.toByteArray()), null , null ); + + _addDimensionAttributes( new ByteArrayInputStream(bos.toByteArray()), newAttrs); + } + catch (Exception e) + { + // unable to fetch image, do not keep the img tag + _tagToIgnore = true ; + getLogger().warn( "Unable to fetch image from URL '" + src + "' . Image is ignored." , e); + return ; + } + finally + { + IOUtils.closeQuietly(is); + } } - catch (Exception e) + else { - // unable to fetch image, do not keep the img tag _tagToIgnore = true ; - getLogger().warn( "Unable to fetch image from URL '" + src + "' . Image is ignored." , e); + getLogger().warn( "Don 't know how to fetch image at ' " + src + "'. Image is ignored." ); return ; } - finally - { - IOUtils.closeQuietly(is); - } - } - else - { - _tagToIgnore = true ; - getLogger().warn( "Don 't know how to fetch image at ' " + src + "'. Image is ignored." ); - return ; } - + _copyAttributes(attrs, newAttrs); newAttrs.addAttribute( "", " ametys_src ", " ametys_src ", " CDATA ", ametys_src + " ;" + fileName);

            Unassigned Unassigned
            raphael Raphaël Franchet
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: