Skip to content

Commit

Permalink
Merge pull request #52 from Terralego/manage_images
Browse files Browse the repository at this point in the history
Manage images
  • Loading branch information
submarcos authored May 14, 2020
2 parents cf75a04 + e6a29cd commit 69689d4
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 13 deletions.
9 changes: 7 additions & 2 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
# CHANGELOG

1.2.27.dev0 (XXXX-XX-XX)
=========
CHANGELOG
=========

1.2.27 (2020-04-14)
----------------------------

* Translate img tag in from_html for odt templates


1.2.26 (2020-05-04)
----------------------------
Expand Down
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
'flake8',
'coverage',
'codecov',
'bpython'
]
},
)
2 changes: 1 addition & 1 deletion template_engines/VERSION.md
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.2.27.dev0
1.2.27
46 changes: 38 additions & 8 deletions template_engines/templatetags/odt_tags.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import base64
import logging
import secrets
import random
import re
import requests
import secrets

import requests
from bs4 import BeautifulSoup
from django import template
from django.utils.safestring import mark_safe

from template_engines.backends.utils_odt import ODT_IMAGE
from .utils import get_extension_picture, parse_tag, resize
from .utils import get_extension_picture, parse_tag, resize, get_image_size_and_dimensions_from_uri

register = template.Library()

Expand Down Expand Up @@ -141,6 +141,33 @@ def parse_br(soup):
return soup


def parse_img(soup):
""" Replace img tags with text:p """
imgs = soup.find_all("img")
# TODO: if src starts with http / https, download file and use local path in odt
for img in imgs:
img.name = 'draw:frame'
src = img.attrs.pop('src')
content = soup.new_tag('draw:image')
content.attrs = {
'xlink:href': src,
'xlink:type': "simple",
'xlink:show': "embed",
'xlink:activate': "onload"
}
size, dimensions = get_image_size_and_dimensions_from_uri(src)
img.attrs = {
'draw:style-name': "fr1",
'text:anchor-type': "char",
'svg:width': f"{dimensions[0]}px",
'svg:height': f"{dimensions[1]}px",
'draw:z-index': "37",
}
img.append(content)

return soup


@register.filter()
def from_html(value, is_safe=True):
""" Convert HTML from rte fields to odt compatible format """
Expand All @@ -155,6 +182,7 @@ def from_html(value, is_safe=True):
soup = parse_a(soup)
soup = parse_h(soup)
soup = parse_br(soup)
soup = parse_img(soup)
return mark_safe(str(soup))


Expand Down Expand Up @@ -225,17 +253,18 @@ def image_url_loader(parser, token):
tag_name, args, kwargs = parse_tag(token, parser)
usage = '{{% {tag_name} [url] max_width="5000px" max_height="5000px" ' \
'request="GET" data="{{"data": "example"}}" anchor="as-char" %}}'.format(tag_name=tag_name)
if len(args) > 1 or not all(key in ['max_width', 'max_height', 'request', 'data', 'anchor'] for key in kwargs.keys()):
if len(args) > 1 or not all(
key in ['max_width', 'max_height', 'request', 'data', 'anchor'] for key in kwargs.keys()):
raise template.TemplateSyntaxError("Usage: %s" % usage)
return ImageLoaderNodeURL(*args, **kwargs)


class ImageLoaderNode(template.Node):
def __init__(self, object, max_width=None, max_height=None, anchor=None):
def __init__(self, instance, max_width=None, max_height=None, anchor=None):
# saves the passed obj parameter for later use
# this is a template.Variable, because that way it can be resolved
# against the current context in the render method
self.object = object
self.object = instance
self.max_width = max_width
self.max_height = max_height
self.anchor = anchor
Expand Down Expand Up @@ -280,11 +309,12 @@ def image_loader(parser, token):
- image : content of your picture in binary or base64
Other keys : max_width, max_height, anchor
- max_width : Width of the picture rendered
- max_heigth : Height of the picture rendered
- max_height : Height of the picture rendered
- anchor : Type of anchor, paragraph, as-char, char, frame, page
"""
tag_name, args, kwargs = parse_tag(token, parser)
usage = '{{% {tag_name} [image] max_width="5000px" max_height="5000px" anchor="as-char" %}}'.format(tag_name=tag_name)
usage = '{{% {tag_name} [image] max_width="5000px" max_height="5000px" anchor="as-char" %}}'.format(
tag_name=tag_name)
if len(args) > 1 or not all(key in ['max_width', 'max_height', 'anchor']
for key in kwargs.keys()):
raise template.TemplateSyntaxError("Usage: %s" % usage)
Expand Down
29 changes: 27 additions & 2 deletions template_engines/templatetags/utils.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import re
from io import BytesIO
from urllib.request import urlopen

from PIL import Image

from PIL import Image, ImageFile
from django.template.base import FilterExpression, kwarg_re


Expand Down Expand Up @@ -162,3 +162,28 @@ def get_extension_picture(image):
with Image.open(bimage) as img_reader:
extension = img_reader.format.lower()
return extension


def get_image_size_and_dimensions_from_uri(uri):
""" get image size and dimensions """
if not uri.lower().startswith('http'):
# protect use of urlopen from filesystem read
return None, (None, None)

file = urlopen(uri)
size = file.headers.get("content-length")
dimensions = (None, None)

if size:
size = int(size)
p = ImageFile.Parser()
while True:
data = file.read(1024)
if not data:
break
p.feed(data)
if p.image:
dimensions = p.image.size
break
file.close()
return size, dimensions

0 comments on commit 69689d4

Please sign in to comment.