utopia-tags-gallery 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ZDdhYmIzOTFmYzEyODgzNWUzZDlkNmEyMjQ0NzI2NGFjNThjYWQwZQ==
5
+ data.tar.gz: !binary |-
6
+ MDJmMjY1MDYzNDAyN2E4MGRjMDAyYjZhZGQ4NzFhY2QyNjJhOWFhYw==
7
+ !binary "U0hBNTEy":
8
+ metadata.gz: !binary |-
9
+ NGE0MGU4YTRhZjc3NThkMzU3YTk4Mzg1YTBhYzMzMzUzZjA0NGM1Y2YyODhl
10
+ MGEzNzNiZGVjYTY4M2IwNjMyYzkzNmQwNDlhYjk4M2QzM2E2NTc4NDk3OWFh
11
+ NjVkNDgxYjFlYWQ3MDVkMTczMjhiMzczODM4YmNjNzE0MzZjOWM=
12
+ data.tar.gz: !binary |-
13
+ MDYxN2ZkMzMxNTI4MjhjZGIyMTNmZjgxMjg1NGQ2NzgzMjM4OWYzN2ZlODVm
14
+ Zjg2MGIwMDkxZjgyMTNkOTA2YmIyN2MxZjA4ZTFhZjAzMDRkMjUxZGYyN2Qx
15
+ YmJkNTU0NGIzMzc4ZjIzMGM2NzZjNGRlZWIyYmEzNjExZDU0ZDU=
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in utopia-gallery.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # Utopia::Tags::Gallery
2
+
3
+ Utopia is a website generation framework which provides a robust set of tools
4
+ to build highly complex dynamic websites. It uses the filesystem heavily for
5
+ content and provides frameworks for interacting with files and directories as
6
+ structure representing the website.
7
+
8
+ This package includes a useful gallery component which can be used for
9
+ displaying thumbnails of images, documents and movies.
10
+
11
+ ## Installation
12
+
13
+ Add this line to your website's Gemfile:
14
+
15
+ gem 'utopia-tags-gallery'
16
+
17
+ And then execute:
18
+
19
+ $ bundle
20
+
21
+ ## Contributing
22
+
23
+ 1. Fork it
24
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
25
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
26
+ 4. Push to the branch (`git push origin my-new-feature`)
27
+ 5. Create new Pull Request
28
+
29
+ ## License
30
+
31
+ Released under the MIT license.
32
+
33
+ Copyright, 2012, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
34
+
35
+ Permission is hereby granted, free of charge, to any person obtaining a copy
36
+ of this software and associated documentation files (the "Software"), to deal
37
+ in the Software without restriction, including without limitation the rights
38
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
39
+ copies of the Software, and to permit persons to whom the Software is
40
+ furnished to do so, subject to the following conditions:
41
+
42
+ The above copyright notice and this permission notice shall be included in
43
+ all copies or substantial portions of the Software.
44
+
45
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
46
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
47
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
48
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
49
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
50
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
51
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,85 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'utopia/tags'
22
+
23
+ require 'utopia/tags/gallery/thumbnail'
24
+ require 'utopia/tags/gallery/container'
25
+
26
+ module Utopia
27
+ module Tags
28
+ module Gallery
29
+ class Metadata
30
+ def initialize(metadata)
31
+ @metadata = metadata
32
+ end
33
+
34
+ attr :metadata
35
+
36
+ def [] (key)
37
+ @metadata[key.to_s]
38
+ end
39
+
40
+ def to_s
41
+ @metadata['caption'] || ''
42
+ end
43
+
44
+ def to_html
45
+ to_s.to_html
46
+ end
47
+ end
48
+
49
+ def self.call(transaction, state)
50
+ container = Container.new(transaction.end_tags[-2].node, Utopia::Path.create(state["path"] || "./"))
51
+ metadata = container.metadata
52
+ metadata.default = {}
53
+
54
+ tag_name = state["tag"] || "img"
55
+ container_class = state["class"] || "gallery"
56
+
57
+ options = {}
58
+ options[:process] = state["process"]
59
+ options[:filter] = Regexp.new("(#{state["filetypes"]})$", "i") if state["filetypes"]
60
+
61
+ filter = Regexp.new(state["filter"], Regexp::IGNORECASE) if state["filter"]
62
+
63
+ transaction.tag("div", "class" => container_class) do |node|
64
+ items = container.each(options).sort do |a, b|
65
+ if metadata[a.original.basename]["order"] and metadata[b.original.basename]["order"]
66
+ metadata[a.original.basename]["order"] <=> metadata[b.original.basename]["order"]
67
+ else
68
+ a.original.basename <=> b.original.basename
69
+ end
70
+ end
71
+
72
+ items.each do |path|
73
+ next if filter and !filter.match(path.original.basename)
74
+
75
+ alt = Metadata.new(metadata[path.original.basename])
76
+
77
+ transaction.tag(tag_name, "src" => path, "alt" => alt)
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ Utopia::Tags.register("gallery", Utopia::Tags::Gallery)
@@ -0,0 +1,157 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'fileutils'
22
+
23
+ module Utopia
24
+ module Tags
25
+ module Gallery
26
+ CACHE_DIR = "_cache"
27
+
28
+ class Path
29
+ def initialize(original_path)
30
+ @original_path = original_path
31
+ @cache_root = @original_path.dirname + CACHE_DIR
32
+
33
+ @extensions = {}
34
+ end
35
+
36
+ attr :cache_root
37
+ attr :extensions
38
+
39
+ def original
40
+ @original_path
41
+ end
42
+
43
+ def self.append_suffix(name, suffix, extension = nil)
44
+ components = name.split(".")
45
+
46
+ components.insert(-2, suffix)
47
+
48
+ if (extension)
49
+ components[-1] = extension
50
+ end
51
+
52
+ return components.join(".")
53
+ end
54
+
55
+ def processed(process = nil)
56
+ if process
57
+ name = @original_path.basename
58
+ return cache_root + Path.append_suffix(name, process.to_s, @extensions[process.to_sym])
59
+ else
60
+ return @original_path
61
+ end
62
+ end
63
+
64
+ def to_html(process = nil)
65
+ Tag.new("img", {"src" => path(process)}).to_html
66
+ end
67
+
68
+ def to_s
69
+ @original_path.to_s
70
+ end
71
+
72
+ def method_missing(name, *args)
73
+ return processed(name.to_s)
74
+ end
75
+ end
76
+
77
+ class Container
78
+ include Enumerable
79
+
80
+ def initialize(node, path, processes = Processes::DEFAULT)
81
+ @node = node
82
+ @path = path
83
+
84
+ @processes = processes
85
+ end
86
+
87
+ def metadata
88
+ metadata_path = @node.local_path(@path + "gallery.yaml")
89
+
90
+ if File.exist? metadata_path
91
+ return YAML::load(File.read(metadata_path))
92
+ else
93
+ return {}
94
+ end
95
+ end
96
+
97
+ def each(options = {})
98
+ return to_enum(:each, options) unless block_given?
99
+
100
+ options[:filter] ||= /(jpg|png)$/i
101
+
102
+ paths = []
103
+ local_path = @node.local_path(@path)
104
+
105
+ Dir.entries(local_path).each do |filename|
106
+ next unless filename.match(options[:filter])
107
+
108
+ path = Path.new(@path + filename)
109
+
110
+ process!(path, options[:process]) if options[:process]
111
+
112
+ yield path
113
+ end
114
+ end
115
+
116
+ def process!(image_path, processes)
117
+ # Create the local cache directory if it doesn't exist already
118
+ local_cache_path = @node.local_path(image_path.cache_root)
119
+
120
+ unless File.exist? local_cache_path
121
+ FileUtils.mkdir local_cache_path
122
+ end
123
+
124
+ # Calculate the new name for the processed image
125
+ local_original_path = @node.local_path(image_path.original)
126
+
127
+ if processes.kind_of? String
128
+ processes = processes.split(",").collect{|p| p.split(":")}
129
+ end
130
+
131
+ processes.each do |process_name, extension|
132
+ process_name = process_name.to_sym
133
+
134
+ process = @processes[process_name]
135
+ extension ||= process.default_extension(image_path)
136
+
137
+ image_path.extensions[process_name] = extension if extension
138
+
139
+ local_processed_path = @node.local_path(image_path.processed(process_name))
140
+
141
+ unless File.exists? local_processed_path
142
+ image = Magick::ImageList.new(local_original_path)
143
+ image.scene = 0
144
+
145
+ processed_image = process.call(image)
146
+ processed_image.write(local_processed_path)
147
+
148
+ # Run GC to free up any memory.
149
+ image = processed_image = nil
150
+ GC.start if defined? GC
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+ end
157
+ end
@@ -0,0 +1,115 @@
1
+ # Copyright, 2012, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require 'RMagick'
22
+
23
+ module Utopia
24
+ module Tags
25
+ module Gallery
26
+ module Processes
27
+ class Thumbnail
28
+ def initialize(size = [800, 800])
29
+ @size = size
30
+ end
31
+
32
+ def call(img)
33
+ # Only resize an image if it is bigger than the given size.
34
+ if (img.columns > @size[0] || img.rows > @size[1])
35
+ img.resize_to_fit(*@size)
36
+ else
37
+ img
38
+ end
39
+ end
40
+
41
+ def default_extension(path)
42
+ ext = path.original.extension
43
+
44
+ case ext
45
+ when /pdf/i
46
+ return "png"
47
+ else
48
+ return ext.downcase
49
+ end
50
+ end
51
+ end
52
+
53
+ # Resize the image to fit within the specified dimensions while retaining the aspect ratio of the original image. If necessary, crop the image in the larger dimension.
54
+ class CropThumbnail < Thumbnail
55
+ def call(img)
56
+ img.resize_to_fill(*@size)
57
+ end
58
+ end
59
+
60
+ class CircularCropThumbnail < CropThumbnail
61
+ def call(img)
62
+ img = super(img)
63
+
64
+ # The crop composite doesn't work correcty with unusual colourspaces:
65
+ img.colorspace = Magick::SRGBColorspace
66
+
67
+ circle = Magick::Image.new(*@size)
68
+ gc = Magick::Draw.new
69
+ gc.fill('black')
70
+ gc.circle(@size[0] / 2.0, @size[1] / 2.0, @size[0] / 2.0, 1)
71
+ gc.draw(circle)
72
+
73
+ mask = circle.blur_image(0,1).negate
74
+
75
+ mask.matte = false
76
+ img.matte = true
77
+
78
+ img.composite!(mask, Magick::CenterGravity, Magick::CopyOpacityCompositeOp)
79
+ end
80
+ end
81
+
82
+ class DocumentThumbnail < Thumbnail
83
+ def call(img)
84
+ img = super(img)
85
+
86
+ img.colorspace = Magick::SRGBColorspace
87
+
88
+ return img
89
+ end
90
+
91
+ def default_extension(path)
92
+ return "png"
93
+ end
94
+ end
95
+
96
+ class PhotoThumbnail < Thumbnail
97
+ def default_extension(path)
98
+ return "jpeg"
99
+ end
100
+ end
101
+
102
+ DEFAULT = {
103
+ :document => Processes::DocumentThumbnail.new([300, 300]),
104
+ :photo => Processes::PhotoThumbnail.new([300, 300]),
105
+
106
+ :square => Processes::CropThumbnail.new([300, 300]),
107
+ :circle => Processes::CircularCropThumbnail.new([300, 300]),
108
+
109
+ :large => Processes::Thumbnail.new([800, 800]),
110
+ :small => Processes::Thumbnail.new([300, 300]),
111
+ }
112
+ end
113
+ end
114
+ end
115
+ end
@@ -0,0 +1,7 @@
1
+ module Utopia
2
+ module Tags
3
+ module Gallery
4
+ VERSION = "0.12.0"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'utopia/tags/gallery/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "utopia-tags-gallery"
8
+ spec.version = Utopia::Tags::Gallery::VERSION
9
+ spec.authors = ["Samuel Williams"]
10
+ spec.email = ["samuel.williams@oriontransfer.co.nz"]
11
+ spec.description = <<-EOF
12
+ Utopia is a website generation framework which provides a robust set of tools
13
+ to build highly complex dynamic websites. It uses the filesystem heavily for
14
+ content and provides frameworks for interacting with files and directories as
15
+ structure representing the website.
16
+
17
+ This package includes a useful gallery component which can be used for
18
+ displaying thumbnails of images, documents and movies.
19
+ EOF
20
+ spec.summary = %q{A gallery tag for use with Utopia web framework.}
21
+ spec.homepage = ""
22
+ spec.license = "MIT"
23
+
24
+ spec.files = `git ls-files`.split($/)
25
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
26
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
27
+ spec.require_paths = ["lib"]
28
+
29
+ spec.add_development_dependency "bundler", "~> 1.3"
30
+ spec.add_development_dependency "rake"
31
+
32
+ spec.add_dependency "utopia", "~> 0.12.0"
33
+ spec.add_dependency "rmagick"
34
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: utopia-tags-gallery
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.12.0
5
+ platform: ruby
6
+ authors:
7
+ - Samuel Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-04-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ! '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: utopia
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: 0.12.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 0.12.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: rmagick
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ! '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: ! "\t\tUtopia is a website generation framework which provides a robust
70
+ set of tools\n\t\tto build highly complex dynamic websites. It uses the filesystem
71
+ heavily for\n\t\tcontent and provides frameworks for interacting with files and
72
+ directories as\n\t\tstructure representing the website.\n\n\t\tThis package includes
73
+ a useful gallery component which can be used for\n\t\tdisplaying thumbnails of images,
74
+ documents and movies.\n"
75
+ email:
76
+ - samuel.williams@oriontransfer.co.nz
77
+ executables: []
78
+ extensions: []
79
+ extra_rdoc_files: []
80
+ files:
81
+ - .gitignore
82
+ - Gemfile
83
+ - README.md
84
+ - Rakefile
85
+ - lib/utopia/tags/gallery.rb
86
+ - lib/utopia/tags/gallery/container.rb
87
+ - lib/utopia/tags/gallery/thumbnail.rb
88
+ - lib/utopia/tags/gallery/version.rb
89
+ - utopia-tags-gallery.gemspec
90
+ homepage: ''
91
+ licenses:
92
+ - MIT
93
+ metadata: {}
94
+ post_install_message:
95
+ rdoc_options: []
96
+ require_paths:
97
+ - lib
98
+ required_ruby_version: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ! '>='
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ! '>='
106
+ - !ruby/object:Gem::Version
107
+ version: '0'
108
+ requirements: []
109
+ rubyforge_project:
110
+ rubygems_version: 2.0.2
111
+ signing_key:
112
+ specification_version: 4
113
+ summary: A gallery tag for use with Utopia web framework.
114
+ test_files: []