sinicum 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.cane +19 -0
- data/.gitignore +14 -0
- data/.rubocop.yml +30 -0
- data/.travis.yml +14 -0
- data/Gemfile +4 -0
- data/LICENSE +24 -0
- data/README.md +327 -0
- data/Rakefile +37 -0
- data/app/assets/javascripts/sinicum/magnolia_client.js.coffee +233 -0
- data/app/controllers/sinicum/controller_base.rb +173 -0
- data/app/controllers/sinicum/controllers/cache_aware.rb +16 -0
- data/app/controllers/sinicum/controllers/global_state_cache.rb +83 -0
- data/app/helpers/sinicum/helper_utils.rb +152 -0
- data/app/helpers/sinicum/mgnl_helper.rb +145 -0
- data/app/helpers/sinicum/mgnl_helper5.rb +7 -0
- data/app/helpers/sinicum/mgnl_image_helper.rb +26 -0
- data/app/helpers/sinicum/taglib_helper5.rb +166 -0
- data/gemfiles/Gemfile-3.2 +6 -0
- data/gemfiles/Gemfile-4.0 +6 -0
- data/lib/generators/sinicum/install_generator.rb +162 -0
- data/lib/generators/sinicum/templates/VersionHandler.java +18 -0
- data/lib/generators/sinicum/templates/config/default/log4j-development.xml +203 -0
- data/lib/generators/sinicum/templates/config/default/log4j.xml +200 -0
- data/lib/generators/sinicum/templates/config/default/magnolia-author.properties +63 -0
- data/lib/generators/sinicum/templates/config/default/magnolia-public01.properties +63 -0
- data/lib/generators/sinicum/templates/config/default/magnolia.properties +63 -0
- data/lib/generators/sinicum/templates/config/repo-conf/jackrabbit-bundle-postgres-search-author.xml +73 -0
- data/lib/generators/sinicum/templates/config/repo-conf/jackrabbit-bundle-postgres-search-public01.xml +73 -0
- data/lib/generators/sinicum/templates/config/repo-conf/jackrabbit-bundle-postgres-search.xml +70 -0
- data/lib/generators/sinicum/templates/magnolia/config.modules.myproject.dialogs.xml +1625 -0
- data/lib/generators/sinicum/templates/magnolia/config.modules.myproject.templates.xml +247 -0
- data/lib/generators/sinicum/templates/module-config.xml +13 -0
- data/lib/generators/sinicum/templates/module-pom.xml +67 -0
- data/lib/generators/sinicum/templates/project-pom.xml +104 -0
- data/lib/generators/sinicum/templates/rails/_article.html.haml +15 -0
- data/lib/generators/sinicum/templates/rails/_content.html.haml +2 -0
- data/lib/generators/sinicum/templates/rails/_meta.html.haml +9 -0
- data/lib/generators/sinicum/templates/rails/application.html.haml +11 -0
- data/lib/generators/sinicum/templates/rails/content_controller.rb +5 -0
- data/lib/generators/sinicum/templates/rails/imaging.yml +8 -0
- data/lib/generators/sinicum/templates/rails/sinicum_server.yml +15 -0
- data/lib/sinicum.rb +53 -0
- data/lib/sinicum/content/aggregator.rb +173 -0
- data/lib/sinicum/content/website_content_resolver.rb +10 -0
- data/lib/sinicum/engine.rb +23 -0
- data/lib/sinicum/imaging.rb +29 -0
- data/lib/sinicum/imaging/config.rb +133 -0
- data/lib/sinicum/imaging/converter.rb +81 -0
- data/lib/sinicum/imaging/default_converter.rb +20 -0
- data/lib/sinicum/imaging/image_size_converter.rb +52 -0
- data/lib/sinicum/imaging/imaging.rb +171 -0
- data/lib/sinicum/imaging/imaging_file.rb +115 -0
- data/lib/sinicum/imaging/imaging_middleware.rb +56 -0
- data/lib/sinicum/imaging/max_size_converter.rb +39 -0
- data/lib/sinicum/imaging/resize_crop_converter.rb +35 -0
- data/lib/sinicum/jcr/api_client.rb +50 -0
- data/lib/sinicum/jcr/api_queries.rb +37 -0
- data/lib/sinicum/jcr/cache/global_cache.rb +26 -0
- data/lib/sinicum/jcr/dam/document.rb +57 -0
- data/lib/sinicum/jcr/dam/image.rb +40 -0
- data/lib/sinicum/jcr/jcr_configuration.rb +67 -0
- data/lib/sinicum/jcr/mgnl4_compatibility.rb +11 -0
- data/lib/sinicum/jcr/node.rb +268 -0
- data/lib/sinicum/jcr/node_initializer.rb +16 -0
- data/lib/sinicum/jcr/node_queries.rb +101 -0
- data/lib/sinicum/jcr/query_sanitizer.rb +24 -0
- data/lib/sinicum/jcr/type_translator.rb +38 -0
- data/lib/sinicum/jcr/type_translators/component_translator.rb +28 -0
- data/lib/sinicum/jcr/type_translators/dam_translator.rb +33 -0
- data/lib/sinicum/jcr/type_translators/data_translator.rb +31 -0
- data/lib/sinicum/jcr/type_translators/default_translator.rb +13 -0
- data/lib/sinicum/jcr/type_translators/translator_base.rb +40 -0
- data/lib/sinicum/logger.rb +28 -0
- data/lib/sinicum/navigation/default_navigation_element.rb +30 -0
- data/lib/sinicum/navigation/navigation_element.rb +39 -0
- data/lib/sinicum/navigation/navigation_element_list.rb +33 -0
- data/lib/sinicum/navigation/navigation_handler.rb +95 -0
- data/lib/sinicum/navigation/navigation_status.rb +27 -0
- data/lib/sinicum/templating/area_handler.rb +33 -0
- data/lib/sinicum/templating/dialog_resolver.rb +26 -0
- data/lib/sinicum/templating/templating_utils.rb +24 -0
- data/lib/sinicum/util.rb +12 -0
- data/lib/sinicum/version.rb +3 -0
- data/script/cibuild +31 -0
- data/sinicum.gemspec +29 -0
- data/spec/controllers/sinicum/controller_base_spec.rb +53 -0
- data/spec/controllers/sinicum/controllers/global_state_cache_spec.rb +35 -0
- data/spec/dummy/REVISION +1 -0
- data/spec/dummy/Rakefile +7 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/views/application/index.html.erb +1 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/layout_name.html.erb +0 -0
- data/spec/dummy/app/views/layouts/my-module/test.html.erb +0 -0
- data/spec/dummy/app/views/layouts/my_module/test.html.erb +0 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +45 -0
- data/spec/dummy/config/boot.rb +10 -0
- data/spec/dummy/config/database.yml +22 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +24 -0
- data/spec/dummy/config/environments/production.rb +51 -0
- data/spec/dummy/config/environments/test.rb +34 -0
- data/spec/dummy/config/imaging.yml +7 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/inflections.rb +10 -0
- data/spec/dummy/config/initializers/mime_types.rb +5 -0
- data/spec/dummy/config/initializers/secret_token.rb +11 -0
- data/spec/dummy/config/initializers/session_store.rb +8 -0
- data/spec/dummy/config/locales/en.yml +5 -0
- data/spec/dummy/config/routes.rb +59 -0
- data/spec/dummy/config/sinicum_server.yml +13 -0
- data/spec/dummy/public/404.html +26 -0
- data/spec/dummy/public/422.html +26 -0
- data/spec/dummy/public/500.html +26 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/public/javascripts/application.js +2 -0
- data/spec/dummy/public/javascripts/controls.js +965 -0
- data/spec/dummy/public/javascripts/dragdrop.js +974 -0
- data/spec/dummy/public/javascripts/effects.js +1123 -0
- data/spec/dummy/public/javascripts/prototype.js +6001 -0
- data/spec/dummy/public/javascripts/rails.js +191 -0
- data/spec/dummy/public/stylesheets/.gitkeep +0 -0
- data/spec/dummy/script/rails +6 -0
- data/spec/fixtures/api/cache_global.json +3 -0
- data/spec/fixtures/api/content_mgnl5.json +22 -0
- data/spec/fixtures/api/default_json.json.erb +47 -0
- data/spec/fixtures/api/default_json_mgnl5.json.erb +27 -0
- data/spec/fixtures/api/file.json +73 -0
- data/spec/fixtures/api/file_mgnl5.json +51 -0
- data/spec/fixtures/api/homepage.json +1497 -0
- data/spec/fixtures/api/homepage_parent.json +483 -0
- data/spec/fixtures/api/image.json +73 -0
- data/spec/fixtures/api/image_mgnl5.json +50 -0
- data/spec/fixtures/api/navigation_children.json +3107 -0
- data/spec/fixtures/api/navigation_parents.json +25 -0
- data/spec/fixtures/api/product.json +2084 -0
- data/spec/fixtures/api/query_result.json +61 -0
- data/spec/fixtures/mock_content.rb +6 -0
- data/spec/fixtures/mock_image.gif +0 -0
- data/spec/helpers/sinicum/helper_utils_spec.rb +55 -0
- data/spec/helpers/sinicum/mgnl_helper_spec.rb +315 -0
- data/spec/helpers/sinicum/mgnl_image_helper_spec.rb +103 -0
- data/spec/sinicum/content/aggregator_spec.rb +91 -0
- data/spec/sinicum/content/website_content_resolver_spec.rb +14 -0
- data/spec/sinicum/imaging/config_spec.rb +50 -0
- data/spec/sinicum/imaging/converter_spec.rb +41 -0
- data/spec/sinicum/imaging/image_size_converter_spec.rb +27 -0
- data/spec/sinicum/imaging/imaging.yml +15 -0
- data/spec/sinicum/imaging/imaging_file_spec.rb +125 -0
- data/spec/sinicum/imaging/imaging_middleware_spec.rb +79 -0
- data/spec/sinicum/imaging/max_size_converter_spec.rb +52 -0
- data/spec/sinicum/imaging/resize_crop_converter_spec.rb +18 -0
- data/spec/sinicum/imaging_spec.rb +13 -0
- data/spec/sinicum/jcr/api_client_spec.rb +69 -0
- data/spec/sinicum/jcr/cache/global_cache_spec.rb +29 -0
- data/spec/sinicum/jcr/dam/document_spec.rb +81 -0
- data/spec/sinicum/jcr/dam/image_spec.rb +46 -0
- data/spec/sinicum/jcr/jcr_configuration_spec.rb +57 -0
- data/spec/sinicum/jcr/mgnl4_compatibility_spec.rb +10 -0
- data/spec/sinicum/jcr/node_queries_spec.rb +113 -0
- data/spec/sinicum/jcr/node_spec.rb +261 -0
- data/spec/sinicum/jcr/query_sanitizer_spec.rb +26 -0
- data/spec/sinicum/jcr/type_translator_spec.rb +42 -0
- data/spec/sinicum/jcr/type_translators/component_translator_spec.rb +71 -0
- data/spec/sinicum/jcr/type_translators/data_translator_spec.rb +38 -0
- data/spec/sinicum/jcr/type_translators/default_translator_spec.rb +19 -0
- data/spec/sinicum/navigation/default_navigation_element_spec.rb +45 -0
- data/spec/sinicum/navigation/navigation_handler_spec.rb +71 -0
- data/spec/sinicum/templating/dialog_resolver_spec.rb +13 -0
- data/spec/sinicum/util_spec.rb +34 -0
- data/spec/spec_helper.rb +42 -0
- data/spec/support/default_node_reader.rb +40 -0
- metadata +434 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'digest/md5'
|
2
|
+
require 'open3'
|
3
|
+
|
4
|
+
module Sinicum
|
5
|
+
module Imaging
|
6
|
+
# Collection of helper methods common to Converters
|
7
|
+
module Converter
|
8
|
+
CONVERTER_VERSION = "1" # change to change Hash signature
|
9
|
+
PNG_OPTIMIZER_SUFFIX = "-fs8.png"
|
10
|
+
|
11
|
+
attr_writer :document
|
12
|
+
|
13
|
+
def initialize(configuration)
|
14
|
+
@x = configuration['x'] || ''
|
15
|
+
@y = configuration['y'] || ''
|
16
|
+
@render_type = configuration['render_type']
|
17
|
+
@hires_factor = configuration['hires_factor'] || 1.0
|
18
|
+
@configuration = configuration
|
19
|
+
end
|
20
|
+
|
21
|
+
# Computes a standard hash for a converted image, consisting of `x`, `y`, `render_type`
|
22
|
+
# and `format`.
|
23
|
+
#
|
24
|
+
# @return [String] A hash based on the current converter's configuration
|
25
|
+
def config_hash
|
26
|
+
digest = Digest::MD5.hexdigest(
|
27
|
+
"#{@x}-#{@y}-#{@hires_factor}-#{@render_type}-#{@format}-#{CONVERTER_VERSION}")
|
28
|
+
digest
|
29
|
+
end
|
30
|
+
|
31
|
+
# Returns the interlace command line option if an image is large enough
|
32
|
+
# (> 80px x 80px)
|
33
|
+
#
|
34
|
+
# @param [String, Fixnum] x the x size of an image
|
35
|
+
# @param [String, Fixnum] y the y size of an image
|
36
|
+
# @return [String] the command line option to interlace an image or an empty String
|
37
|
+
def interlace_option(x, y)
|
38
|
+
x.to_i * y.to_i > 80 * 80 ? "-interlace plane" : ""
|
39
|
+
end
|
40
|
+
|
41
|
+
def ratio(x, y)
|
42
|
+
x.to_f / y.to_f
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def device_pixel_size(pixel)
|
48
|
+
px = pixel.to_f * @hires_factor.to_f
|
49
|
+
if px == 0
|
50
|
+
''
|
51
|
+
else
|
52
|
+
px.round
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def quality_option
|
57
|
+
"-quality 50" if @hires_factor && @hires_factor > 1.5
|
58
|
+
end
|
59
|
+
|
60
|
+
def optimize_png_outfile(outfile_path)
|
61
|
+
return unless format == "png"
|
62
|
+
cmd = "pngquant -- \"#{outfile_path}\""
|
63
|
+
exec_command(cmd)
|
64
|
+
cmd = "mv \"#{outfile_path}#{PNG_OPTIMIZER_SUFFIX}\" \"#{outfile_path}\""
|
65
|
+
exec_command(cmd)
|
66
|
+
rescue
|
67
|
+
# Fail silently
|
68
|
+
end
|
69
|
+
|
70
|
+
def exec_command(command)
|
71
|
+
status = nil
|
72
|
+
Open3.popen2(command) do |stdin, stdout, wait_thr|
|
73
|
+
status = wait_thr.value.exitstatus
|
74
|
+
end
|
75
|
+
if status != 0
|
76
|
+
fail "Command '#{command}' failed with exit status #{status}"
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sinicum
|
2
|
+
module Imaging
|
3
|
+
# Internal: Simple converter that simply serves a copy of the original file.
|
4
|
+
class DefaultConverter
|
5
|
+
include Converter
|
6
|
+
include Sinicum::Logger
|
7
|
+
|
8
|
+
def initialize(configuration)
|
9
|
+
end
|
10
|
+
|
11
|
+
def convert(infile_path, outfile_path)
|
12
|
+
`cp #{infile_path} #{outfile_path}`
|
13
|
+
end
|
14
|
+
|
15
|
+
def format
|
16
|
+
".#{@document[:document][:extension]}" if @document && @document[:document]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module Sinicum
|
2
|
+
module Imaging
|
3
|
+
# Public: Calculates the size of an image based on the converter used to
|
4
|
+
# render the image.
|
5
|
+
class ImageSizeConverter
|
6
|
+
DEFAULT_WORKSPACE = "dam"
|
7
|
+
|
8
|
+
def initialize(image_or_jcr_path, converter_name, options = {})
|
9
|
+
if image_or_jcr_path.is_a?(String)
|
10
|
+
workspace = options[:workspace].presence || DEFAULT_WORKSPACE
|
11
|
+
@image = Sinicum::Jcr::Node.find_by_path(workspace, image_or_jcr_path)
|
12
|
+
elsif image_or_jcr_path.respond_to?(:width) && image_or_jcr_path.respond_to?(:height)
|
13
|
+
@image = image_or_jcr_path
|
14
|
+
end
|
15
|
+
@converter_name = converter_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def width
|
19
|
+
unless defined?(@width)
|
20
|
+
if converter.respond_to?(:converted_size)
|
21
|
+
@width = converter.converted_size[0]
|
22
|
+
else
|
23
|
+
@width = @image.width
|
24
|
+
end
|
25
|
+
end
|
26
|
+
@width
|
27
|
+
end
|
28
|
+
|
29
|
+
def height
|
30
|
+
unless defined?(@height)
|
31
|
+
if converter.respond_to?(:converted_size)
|
32
|
+
@height = converter.converted_size[1]
|
33
|
+
else
|
34
|
+
@height = @image.height
|
35
|
+
end
|
36
|
+
end
|
37
|
+
@height
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def converter
|
43
|
+
unless defined?(@converter)
|
44
|
+
conf = Config.read_configuration
|
45
|
+
@converter = conf.converter(@converter_name)
|
46
|
+
@converter.document = @image if @converter
|
47
|
+
end
|
48
|
+
@converter
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
module Sinicum
|
5
|
+
module Imaging
|
6
|
+
# Internal: Class that handles more or less all of the imaging
|
7
|
+
# functionality.
|
8
|
+
class Imaging
|
9
|
+
RENDER_MUTEX = Mutex.new
|
10
|
+
include Sinicum::Logger
|
11
|
+
|
12
|
+
attr_reader :fingerprint
|
13
|
+
|
14
|
+
# Render the image from path `original_path` with the renderer `renderer`
|
15
|
+
#
|
16
|
+
# @param [String] original_path The original path of the image.
|
17
|
+
# @param [String] renderer The name of the renderer
|
18
|
+
# @return [RenderResult] The result of the conversion
|
19
|
+
def self.rendered_resource(original_path, extension, renderer, fingerprint, workspace = nil)
|
20
|
+
imaging = Imaging.new(original_path, extension, renderer, fingerprint, workspace)
|
21
|
+
result = imaging.fetch_image
|
22
|
+
result
|
23
|
+
end
|
24
|
+
|
25
|
+
def initialize(original_path, extension, renderer, fingerprint, workspace = nil)
|
26
|
+
@original_path = original_path
|
27
|
+
@extension = extension
|
28
|
+
@renderer = renderer
|
29
|
+
@fingerprint = fingerprint
|
30
|
+
@workspace = workspace
|
31
|
+
end
|
32
|
+
|
33
|
+
def fetch_image
|
34
|
+
result = nil
|
35
|
+
@image, @doc = find_image_objects_by_path(@original_path)
|
36
|
+
if @image && @doc
|
37
|
+
if convert_file?
|
38
|
+
result = perform_conversion
|
39
|
+
else
|
40
|
+
format = converter.format
|
41
|
+
mime_type =
|
42
|
+
case format
|
43
|
+
when "gif" then "image/gif"
|
44
|
+
when "png" then "image/png"
|
45
|
+
when "ogv" then "video/ogg"
|
46
|
+
when "mp4" then "video/mp4"
|
47
|
+
when "m4a" then "audio/mp4"
|
48
|
+
when "ogg" then "audio/ogg"
|
49
|
+
when "webm" then "audio/webm"
|
50
|
+
else "image/jpeg"
|
51
|
+
end
|
52
|
+
result = RenderResult.new(
|
53
|
+
file_rendered, mime_type,
|
54
|
+
"#{@doc[:fileName]}.#{@doc[:extension]}", fingerprint)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
result
|
58
|
+
end
|
59
|
+
|
60
|
+
# The temporary file as it comes out of the repository
|
61
|
+
def file_out
|
62
|
+
@_file_out ||= File.join(config_data.tmp_dir, @renderer + "-" + "out" + "-" + random)
|
63
|
+
end
|
64
|
+
|
65
|
+
# The temporary file the converter writes to
|
66
|
+
def file_converted
|
67
|
+
@_file_converted ||= File.join(config_data.tmp_dir, @renderer + "-" + "converted" +
|
68
|
+
"-" + random + "." + converter.format)
|
69
|
+
end
|
70
|
+
|
71
|
+
# The "final" file to be sent to the client
|
72
|
+
def file_rendered
|
73
|
+
@_file_rendered ||= File.join(config_data.file_dir, "/" + @renderer + "-" +
|
74
|
+
converter.config_hash + "-" + @image.uuid + "." +
|
75
|
+
converter.format)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Finds the image objects by path
|
79
|
+
#
|
80
|
+
# @param [String] original_path The original path
|
81
|
+
# @return [Array] An `Array` in the form `[Image, Document]`
|
82
|
+
def find_image_objects_by_path(original_path)
|
83
|
+
result = [nil, nil]
|
84
|
+
if @workspace == :dam
|
85
|
+
image_node_path = original_path.gsub(/^\/dam/, "")
|
86
|
+
image = Sinicum::Jcr::Node.find_by_path("dam", image_node_path)
|
87
|
+
elsif @workspace == :dms
|
88
|
+
image_node_path = original_path.gsub(/^\/dms/, "")
|
89
|
+
image = Sinicum::Jcr::Node.find_by_path("dms", image_node_path)
|
90
|
+
end
|
91
|
+
if image
|
92
|
+
doc = image.properties
|
93
|
+
result = [image, doc]
|
94
|
+
end
|
95
|
+
result
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def perform_conversion
|
101
|
+
RENDER_MUTEX.synchronize {
|
102
|
+
out_file = File.open(file_out, "wb")
|
103
|
+
out_file.close
|
104
|
+
in_file = File.open(file_converted, "wb")
|
105
|
+
begin
|
106
|
+
write_doc_to_tempfile(in_file)
|
107
|
+
in_file.close
|
108
|
+
convert(in_file.path, out_file.path)
|
109
|
+
FileUtils.mv(out_file.path, file_rendered)
|
110
|
+
FileUtils.chmod(0644, file_rendered)
|
111
|
+
RenderResult.new(
|
112
|
+
file_rendered, @doc["jcr:mimeType"],
|
113
|
+
"#{@doc[:fileName]}.#{@doc[:extension]}", fingerprint)
|
114
|
+
rescue => e
|
115
|
+
FileUtils.rm(out_file.path) if File.exist?(out_file.path)
|
116
|
+
raise e
|
117
|
+
ensure
|
118
|
+
FileUtils.rm(in_file.path) if File.exist?(in_file.path)
|
119
|
+
end
|
120
|
+
}
|
121
|
+
end
|
122
|
+
|
123
|
+
def convert(infile_path, outfile_path)
|
124
|
+
converter.convert(infile_path, outfile_path)
|
125
|
+
end
|
126
|
+
|
127
|
+
def write_doc_to_tempfile(tempfile)
|
128
|
+
begin
|
129
|
+
Sinicum::Jcr::Node.stream_attribute(@doc.jcr_workspace, @doc.path, "jcr:data", tempfile)
|
130
|
+
rescue => e
|
131
|
+
logger.error("Cannot write to tempfile: " + e.to_s)
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
def convert_file?
|
136
|
+
last_modified = @doc["jcr:lastModified"]
|
137
|
+
# File.size == 0 is related to a (temporary?) bug on one server
|
138
|
+
# should be possible to remove
|
139
|
+
result = !File.exist?(file_rendered) || File.mtime(file_rendered) <
|
140
|
+
last_modified || File.size(file_rendered) == 0
|
141
|
+
result
|
142
|
+
end
|
143
|
+
|
144
|
+
def random
|
145
|
+
@random ||= "#{Process.pid}-#{rand(1_000_000_000)}"
|
146
|
+
end
|
147
|
+
|
148
|
+
def config_data
|
149
|
+
Config.read_configuration
|
150
|
+
end
|
151
|
+
|
152
|
+
def converter
|
153
|
+
conv = config_data.converter(@renderer)
|
154
|
+
conv.document = @image if conv
|
155
|
+
conv
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
# Internal: Simple wrapper around imaging results.
|
160
|
+
class RenderResult
|
161
|
+
attr_accessor :path, :mime_type, :filename, :fingerprint
|
162
|
+
|
163
|
+
def initialize(path, mime_type, filename, fingerprint = nil)
|
164
|
+
@path = path
|
165
|
+
@mime_type = mime_type
|
166
|
+
@filename = filename
|
167
|
+
@fingerprint = fingerprint
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
module Sinicum
|
3
|
+
module Imaging
|
4
|
+
# Representation of a DAM file as seen by the imaging middleware.
|
5
|
+
class ImagingFile
|
6
|
+
ORIGINAL_DAM_PATH_START = ::Sinicum::Imaging.dam_path_prefix + "/"
|
7
|
+
ORIGINAL_DAM_PATH_REPLACEMENT = ::Sinicum::Imaging.path_prefix + "/" +
|
8
|
+
::Sinicum::Imaging.default_converter_name + "/"
|
9
|
+
ORIGINAL_DMS_PATH_START = ::Sinicum::Imaging.dms_path_prefix + "/"
|
10
|
+
ORIGINAL_DMS_PATH_REPLACEMENT = ::Sinicum::Imaging.path_prefix_mgnl4 + "/" +
|
11
|
+
::Sinicum::Imaging.default_converter_name + "/"
|
12
|
+
DEFAULT_CACHE_TIME = 24 * 60 * 60
|
13
|
+
FINGERPRINT_CACHE_TIME = 7 * 24 * 60 * 60
|
14
|
+
|
15
|
+
attr_reader :normalized_request_path, :extension, :fingerprint, :workspace
|
16
|
+
|
17
|
+
# Public: Create a new instance
|
18
|
+
#
|
19
|
+
# path_info - The request's path_info
|
20
|
+
def initialize(path_info)
|
21
|
+
@path_info = path_info
|
22
|
+
set_up
|
23
|
+
end
|
24
|
+
|
25
|
+
def result?
|
26
|
+
!!imaging_result
|
27
|
+
end
|
28
|
+
|
29
|
+
def path
|
30
|
+
imaging_result.path
|
31
|
+
end
|
32
|
+
|
33
|
+
def filename
|
34
|
+
imaging_result.filename
|
35
|
+
end
|
36
|
+
|
37
|
+
def cache_time
|
38
|
+
if fingerprint
|
39
|
+
FINGERPRINT_CACHE_TIME
|
40
|
+
else
|
41
|
+
DEFAULT_CACHE_TIME
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
private
|
46
|
+
|
47
|
+
def imaging_result
|
48
|
+
@imaging_result ||= create_imaging_result
|
49
|
+
end
|
50
|
+
|
51
|
+
def create_imaging_result
|
52
|
+
result = ::Sinicum::Imaging::Imaging.rendered_resource(
|
53
|
+
@file_asset_path, extension, @renderer, fingerprint, @workspace)
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
# Private: "Normalizes" the request path. In particular, a request
|
58
|
+
# to "/dam/something" gets converted to
|
59
|
+
# "/damfiles/default/something".
|
60
|
+
#
|
61
|
+
# Then it extracts the fingerprint and extension, if any of them
|
62
|
+
# exist.
|
63
|
+
def set_up
|
64
|
+
if @path_info.index(ORIGINAL_DAM_PATH_START) == 0
|
65
|
+
path = @path_info.sub(ORIGINAL_DAM_PATH_START, ORIGINAL_DAM_PATH_REPLACEMENT)
|
66
|
+
path = cutoff_document_path_repetition(path)
|
67
|
+
elsif @path_info.index(ORIGINAL_DMS_PATH_START) == 0
|
68
|
+
path = @path_info.sub(ORIGINAL_DMS_PATH_START, ORIGINAL_DMS_PATH_REPLACEMENT)
|
69
|
+
path = cutoff_document_path_repetition(path)
|
70
|
+
else
|
71
|
+
path = @path_info.dup
|
72
|
+
end
|
73
|
+
if path =~ /^\/dam/
|
74
|
+
@workspace = :dam
|
75
|
+
elsif path =~ /^\/dms/
|
76
|
+
@workspace = :dms
|
77
|
+
end
|
78
|
+
@normalized_request_path, @extension, @fingerprint = extract_fingerprint(path)
|
79
|
+
renderer_image = normalized_request_path[
|
80
|
+
::Sinicum::Imaging.path_prefix.size + 1, normalized_request_path.size]
|
81
|
+
@renderer = renderer_image[0, renderer_image.index("/")]
|
82
|
+
@file_asset_path = renderer_image[@renderer.size, renderer_image.size]
|
83
|
+
nil
|
84
|
+
end
|
85
|
+
|
86
|
+
def extract_fingerprint(path)
|
87
|
+
if match = path.match(/(.+?)-(\h{32})(\.\w+)?$/)
|
88
|
+
extension = nil
|
89
|
+
extension = match[3][1..match[3].length] if match[3]
|
90
|
+
[match[1], extension, match[2]]
|
91
|
+
else
|
92
|
+
extension = nil
|
93
|
+
if match = path.match(/(.+)\.(\w+)$/)
|
94
|
+
extension = match[2]
|
95
|
+
path = match[1]
|
96
|
+
end
|
97
|
+
[path, extension, nil]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
def cutoff_document_path_repetition(path)
|
102
|
+
parts = path.split("/")
|
103
|
+
if parts.size > 3
|
104
|
+
if match = parts.last.match(/(.+)(\.\w+)$/)
|
105
|
+
last_part = match[1]
|
106
|
+
if last_part == parts[parts.size - 2]
|
107
|
+
path = path[0..(path.rindex("/") - 1)] + match[2]
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
path
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
module Sinicum
|
2
|
+
module Imaging
|
3
|
+
# Public: Rack middleware to handle a request to the imaging fuctionality.
|
4
|
+
class ImagingMiddleware < Rack::File
|
5
|
+
SUFFIX_REGEX = /\.\w+$/
|
6
|
+
DEFAULT_CACHE_TIME = 24 * 60 * 60
|
7
|
+
|
8
|
+
def initialize(app)
|
9
|
+
@app = app
|
10
|
+
end
|
11
|
+
|
12
|
+
def call(env)
|
13
|
+
if on_imaging_path?(env['PATH_INFO'])
|
14
|
+
dup._call(env)
|
15
|
+
else
|
16
|
+
@app.call(env)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def _call(env)
|
21
|
+
unless ALLOWED_VERBS.include? env["REQUEST_METHOD"]
|
22
|
+
return fail(405, "Method Not Allowed")
|
23
|
+
end
|
24
|
+
request = Rack::Request.new(env)
|
25
|
+
imaging_file = ImagingFile.new(request.path_info)
|
26
|
+
if imaging_file.result?
|
27
|
+
@path = imaging_file.path
|
28
|
+
available = begin
|
29
|
+
F.file?(@path) && F.readable?(@path)
|
30
|
+
rescue SystemCallError
|
31
|
+
false
|
32
|
+
end
|
33
|
+
end
|
34
|
+
if available
|
35
|
+
@headers = {}
|
36
|
+
@headers["Content-Disposition"] = "inline; filename=\"#{imaging_file.filename}\""
|
37
|
+
if Rails.configuration.action_controller.perform_caching
|
38
|
+
@headers["Cache-Control"] = "max-age=#{imaging_file.cache_time}, public"
|
39
|
+
end
|
40
|
+
serving(env)
|
41
|
+
else
|
42
|
+
fail(404, "File not found: #{request.path_info}")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
private
|
47
|
+
|
48
|
+
def on_imaging_path?(path)
|
49
|
+
path && (path.index(::Sinicum::Imaging.path_prefix) == 0 ||
|
50
|
+
path.index(ImagingFile::ORIGINAL_DAM_PATH_START) == 0 ||
|
51
|
+
path.index(::Sinicum::Imaging.path_prefix_mgnl4) == 0 ||
|
52
|
+
path.index(ImagingFile::ORIGINAL_DMS_PATH_START) == 0)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|