From 86877cfd9e9dda8e8e6309707a9c7329081f4680 Mon Sep 17 00:00:00 2001 From: eugen neagoe Date: Mon, 15 Jul 2019 14:54:49 +0300 Subject: [PATCH] Lazy load image content Instead of reading the image content from files/objects at declaration, use a lambda to delay reading the image data only when the image is actually inserted in the template. --- lib/sablon/content.rb | 16 ++++++++++++---- lib/sablon/operations.rb | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/lib/sablon/content.rb b/lib/sablon/content.rb index 34d7a036..aa3c3711 100644 --- a/lib/sablon/content.rb +++ b/lib/sablon/content.rb @@ -184,15 +184,23 @@ def inspect "#" end + # image data being lazily loaded by procs, we need to actually execute + # the procs to test that the generated images are the same + def ==(other) + self.class == other.class && + name == other.name && properties == other.properties && + data.call == other.data.call + end + def initialize(source, attributes = {}) attributes = Hash[attributes.map { |k, v| [k.to_s, v] }] # If the source object is readable, use it as such otherwise open - # and read the content + # and lazily read the content if source.respond_to?(:read) name, img_data = process_readable(source, attributes) else name = File.basename(source) - img_data = IO.binread(source) + img_data = -> { IO.binread(source) } end # super name, img_data @@ -233,8 +241,8 @@ def process_readable(source, attributes) raise ArgumentError, "Error: Could not determine filename from source, try: `Sablon.content(readable_obj, filename: '...')`" end end - # - [File.basename(name), source.read] + # delay loading the image with a lambda + [File.basename(name), -> { source.read } ] end # Convert centimeters or inches to Word specific emu format diff --git a/lib/sablon/operations.rb b/lib/sablon/operations.rb index a2cf7a83..0f2992d6 100644 --- a/lib/sablon/operations.rb +++ b/lib/sablon/operations.rb @@ -136,7 +136,7 @@ def set_local_rid(env, image) rel_attr = { Type: 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image' } - rid = env.document.add_media(image.name, image.data, rel_attr) + rid = env.document.add_media(image.name, image.data.call, rel_attr) image.rid_by_file[env.document.current_entry] = rid elsif image.rid_by_file[env.document.current_entry].nil? # locate an existing relationship and duplicate it