utopia-extras 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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-extras.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,52 @@
1
+ # Utopia::Extras
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 of contributions includes things which aren't available on all
9
+ platforms or which are not critical to the core of utopia, but are useful in
10
+ typical every-day deployments.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your website's Gemfile:
15
+
16
+ gem 'utopia-extras'
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ ## Contributing
23
+
24
+ 1. Fork it
25
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
26
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
27
+ 4. Push to the branch (`git push origin my-new-feature`)
28
+ 5. Create new Pull Request
29
+
30
+ ## License
31
+
32
+ Released under the MIT license.
33
+
34
+ Copyright, 2012, by [Samuel G. D. Williams](http://www.codeotaku.com/samuel-williams).
35
+
36
+ Permission is hereby granted, free of charge, to any person obtaining a copy
37
+ of this software and associated documentation files (the "Software"), to deal
38
+ in the Software without restriction, including without limitation the rights
39
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
40
+ copies of the Software, and to permit persons to whom the Software is
41
+ furnished to do so, subject to the following conditions:
42
+
43
+ The above copyright notice and this permission notice shall be included in
44
+ all copies or substantial portions of the Software.
45
+
46
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
47
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
48
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
49
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
50
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
51
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
52
+ THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'test'
6
+ end
7
+
8
+ desc "Run tests"
9
+ task :default => :test
@@ -0,0 +1,21 @@
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/extras/version"
@@ -0,0 +1,25 @@
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
+ module Utopia
22
+ module Extras
23
+ VERSION = "0.11.0"
24
+ end
25
+ end
@@ -0,0 +1,45 @@
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/middleware'
22
+
23
+ module Utopia
24
+ module Middleware
25
+
26
+ class Benchmark
27
+ def initialize(app, options = {})
28
+ @app = app
29
+ @tag = options[:tag] || "{{benchmark}}"
30
+ end
31
+
32
+ def call(env)
33
+ start = Time.now
34
+ response = @app.call(env)
35
+ finish = Time.now
36
+
37
+ time = "%0.4f" % (finish - start)
38
+ env['rack.errors'].puts "Benchmark: Request #{env["PATH_INFO"]} took #{time}s"
39
+
40
+ return response
41
+ end
42
+ end
43
+
44
+ end
45
+ end
@@ -0,0 +1,52 @@
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/middleware'
22
+
23
+ module Utopia
24
+ module Middleware
25
+
26
+ # This class filters a incoming request and only executes a given block if it matches the given filter path.
27
+ class Filter
28
+ def initialize(app, filter, &block)
29
+ @app = app
30
+ @filter = filter
31
+ branch = Rack::Builder.new(&block)
32
+ branch.run(@app)
33
+ @process = branch.to_app
34
+ end
35
+
36
+ def applicable(request)
37
+ return request.path.index(@filter) != nil
38
+ end
39
+
40
+ def call(env)
41
+ request = Rack::Request.new(env)
42
+
43
+ if applicable(request)
44
+ @process.call(env)
45
+ else
46
+ @app.call(env)
47
+ end
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,25 @@
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
+ Utopia::Tags.create("fortune") do |transaction, state|
24
+ "<pre>#{`fortune`.to_html}</pre>"
25
+ end
@@ -0,0 +1,291 @@
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 'RMagick'
24
+ require 'fileutils'
25
+
26
+ class Utopia::Tags::Gallery
27
+ module Processes
28
+ class Thumbnail
29
+ def initialize(size = [800, 800])
30
+ @size = size
31
+ end
32
+
33
+ def call(img)
34
+ # Only resize an image if it is bigger than the given size.
35
+ if (img.columns > @size[0] || img.rows > @size[1])
36
+ img.resize_to_fit(*@size)
37
+ else
38
+ img
39
+ end
40
+ end
41
+
42
+ def default_extension(path)
43
+ ext = path.original.extension
44
+
45
+ case ext
46
+ when /pdf/i
47
+ return "png"
48
+ else
49
+ return ext.downcase
50
+ end
51
+ end
52
+ end
53
+
54
+ # 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.
55
+ class CropThumbnail < Thumbnail
56
+ def call(img)
57
+ img.resize_to_fill(*@size)
58
+ end
59
+ end
60
+
61
+ class DocumentThumbnail < Thumbnail
62
+ def call(img)
63
+ img = super(img)
64
+
65
+ shadow = img.dup
66
+
67
+ shadow = shadow.colorize(1, 1, 1, 'gray50')
68
+ shadow.background_color = 'transparent'
69
+ shadow.border!(10, 10, 'transparent')
70
+
71
+ shadow = shadow.gaussian_blur_channel(5, 5, Magick::AlphaChannel)
72
+
73
+ shadow.composite(img, 5, 5, Magick::OverCompositeOp)
74
+ end
75
+
76
+ def default_extension(path)
77
+ return "png"
78
+ end
79
+ end
80
+
81
+ class PhotoThumbnail < Thumbnail
82
+ def call(img)
83
+ img = super(img)
84
+
85
+ shadow = img.dup
86
+
87
+ shadow = shadow.colorize(1, 1, 1, '#999999ff')
88
+ shadow.background_color = 'transparent'
89
+ shadow.border!(10, 10, '#99999900')
90
+
91
+ shadow = shadow.gaussian_blur_channel(5, 5, Magick::AlphaChannel)
92
+
93
+ shadow.composite(img, 5, 5, Magick::OverCompositeOp)
94
+ end
95
+
96
+ def default_extension(path)
97
+ return "png"
98
+ end
99
+ end
100
+ end
101
+
102
+ CACHE_DIR = "_cache"
103
+ PROCESSES = {
104
+ :pdf_thumbnail => Processes::DocumentThumbnail.new([300, 300]),
105
+ :photo_thumbnail => Processes::PhotoThumbnail.new([300, 300]),
106
+ :large => Processes::Thumbnail.new([800, 800]),
107
+ :square_thumbnail => Processes::CropThumbnail.new([300, 300]),
108
+ :thumbnail => Processes::Thumbnail.new([300, 300])
109
+ }
110
+
111
+ class ImagePath
112
+ def initialize(original_path)
113
+ @original_path = original_path
114
+ @cache_root = @original_path.dirname + CACHE_DIR
115
+
116
+ @extensions = {}
117
+ end
118
+
119
+ attr :cache_root
120
+ attr :extensions
121
+
122
+ def original
123
+ @original_path
124
+ end
125
+
126
+ def self.append_suffix(name, suffix, extension = nil)
127
+ components = name.split(".")
128
+
129
+ components.insert(-2, suffix)
130
+
131
+ if (extension)
132
+ components[-1] = extension
133
+ end
134
+
135
+ return components.join(".")
136
+ end
137
+
138
+ def processed(process = nil)
139
+ if process
140
+ name = @original_path.basename
141
+ return cache_root + ImagePath.append_suffix(name, process.to_s, @extensions[process.to_sym])
142
+ else
143
+ return @original_path
144
+ end
145
+ end
146
+
147
+ def to_html(process = nil)
148
+ Tag.new("img", {"src" => path(process)}).to_html
149
+ end
150
+
151
+ def to_s
152
+ @original_path.to_s
153
+ end
154
+
155
+ def method_missing(name, *args)
156
+ return processed(name.to_s)
157
+ end
158
+ end
159
+
160
+ class ImageMetadata
161
+ def initialize(metadata)
162
+ @metadata = metadata
163
+ end
164
+
165
+ attr :metadata
166
+
167
+ def [] (key)
168
+ @metadata[key.to_s]
169
+ end
170
+
171
+ def to_s
172
+ @metadata['caption'] || ''
173
+ end
174
+
175
+ # A bit of a hack to ease migration.
176
+ def to_html
177
+ to_s.to_html
178
+ end
179
+ end
180
+
181
+ def initialize(node, path)
182
+ @node = node
183
+ @path = path
184
+ end
185
+
186
+ def metadata
187
+ metadata_path = @node.local_path(@path + "gallery.yaml")
188
+
189
+ if File.exist? metadata_path
190
+ return YAML::load(File.read(metadata_path))
191
+ else
192
+ return {}
193
+ end
194
+ end
195
+
196
+ def images(options = {})
197
+ options[:filter] ||= /(jpg|png)$/i
198
+
199
+ paths = []
200
+ local_path = @node.local_path(@path)
201
+
202
+ Dir.entries(local_path).each do |filename|
203
+ next unless filename.match(options[:filter])
204
+
205
+ fullpath = File.join(local_path, filename)
206
+
207
+ paths << ImagePath.new(@path + filename)
208
+ end
209
+
210
+ if options[:process]
211
+ paths.each do |path|
212
+ processed_image(path, options[:process])
213
+ end
214
+ end
215
+
216
+ return paths
217
+ end
218
+
219
+ def processed_image(image_path, processes)
220
+ # Create the local cache directory if it doesn't exist already
221
+ local_cache_path = @node.local_path(image_path.cache_root)
222
+
223
+ unless File.exist? local_cache_path
224
+ FileUtils.mkdir local_cache_path
225
+ end
226
+
227
+ # Calculate the new name for the processed image
228
+ local_original_path = @node.local_path(image_path.original)
229
+
230
+ if processes.kind_of? String
231
+ processes = processes.split(",").collect{|p| p.split(":")}
232
+ end
233
+
234
+ processes.each do |process_name, extension|
235
+ process_name = process_name.to_sym
236
+
237
+ process = PROCESSES[process_name]
238
+ extension ||= process.default_extension(image_path)
239
+
240
+ image_path.extensions[process_name] = extension if extension
241
+
242
+ local_processed_path = @node.local_path(image_path.processed(process_name))
243
+
244
+ unless File.exists? local_processed_path
245
+ image = Magick::ImageList.new(local_original_path)
246
+ image.scene = 0
247
+
248
+ processed_image = process.call(image)
249
+ processed_image.write(local_processed_path)
250
+
251
+ # Run GC to free up any memory.
252
+ processed_image = nil
253
+ GC.start if defined? GC
254
+ end
255
+ end
256
+ end
257
+
258
+ def self.call(transaction, state)
259
+ gallery = new(transaction.end_tags[-2].node, Utopia::Path.create(state["path"] || "./"))
260
+ metadata = gallery.metadata
261
+ metadata.default = {}
262
+
263
+ tag_name = state["tag"] || "img"
264
+ gallery_class = state["class"] || "gallery"
265
+
266
+ options = {}
267
+ options[:process] = state["process"]
268
+ options[:filter] = Regexp.new("(#{state["filetypes"]})$", "i") if state["filetypes"]
269
+
270
+ filter = Regexp.new(state["filter"], Regexp::IGNORECASE) if state["filter"]
271
+
272
+ transaction.tag("div", "class" => gallery_class) do |node|
273
+ images = gallery.images(options).sort do |a, b|
274
+ if (metadata[a.original.basename]["order"] && metadata[b.original.basename]["order"])
275
+ metadata[a.original.basename]["order"] <=> metadata[b.original.basename]["order"]
276
+ else
277
+ a.original.basename <=> b.original.basename
278
+ end
279
+ end
280
+
281
+ images.each do |path|
282
+ next if filter and !filter.match(path.original.basename)
283
+
284
+ alt = ImageMetadata.new(metadata[path.original.basename])
285
+ transaction.tag(tag_name, "src" => path, "alt" => alt)
286
+ end
287
+ end
288
+ end
289
+ end
290
+
291
+ Utopia::Tags.register("gallery", Utopia::Tags::Gallery)
@@ -0,0 +1,37 @@
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
+ Utopia::Tags.create("google_analytics") do |transaction, state|
24
+ html = <<EOF
25
+ <script type="text/javascript">
26
+ var _gaq = _gaq || []; _gaq.push(['_setAccount', #{state[:id].to_quoted_string}]); _gaq.push(['_trackPageview']);
27
+ (function() {
28
+ var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
29
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
30
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
31
+ })();
32
+ </script>
33
+ EOF
34
+
35
+
36
+ transaction.cdata(html)
37
+ end
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'utopia/extras/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "utopia-extras"
8
+ gem.version = Utopia::Extras::VERSION
9
+ gem.authors = ["Samuel Williams"]
10
+ gem.email = ["samuel.williams@oriontransfer.co.nz"]
11
+ gem.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 of contributions includes things which aren't available on all
18
+ platforms or which are not critical to the core of utopia, but are useful in
19
+ typical every-day deployments.
20
+ EOF
21
+ gem.summary = %q{A collection of useful extras for the Utopia framework.}
22
+ gem.homepage = ""
23
+
24
+ gem.files = `git ls-files`.split($/)
25
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
26
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
27
+ gem.require_paths = ["lib"]
28
+
29
+ gem.add_dependency "utopia", "~> 0.11.0"
30
+
31
+ gem.add_dependency "rmagick"
32
+ end
metadata ADDED
@@ -0,0 +1,94 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: utopia-extras
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.11.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Samuel Williams
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-10-26 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: utopia
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.11.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.11.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rmagick
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ description: ! " Utopia is a website generation framework which provides a robust
47
+ set of tools\n to build highly complex dynamic websites. It uses the filesystem
48
+ heavily for\n content and provides frameworks for interacting with files and directories
49
+ as\n structure representing the website.\n\n This package of contributions includes
50
+ things which aren't available on all\n platforms or which are not critical to the
51
+ core of utopia, but are useful in\n typical every-day deployments.\n"
52
+ email:
53
+ - samuel.williams@oriontransfer.co.nz
54
+ executables: []
55
+ extensions: []
56
+ extra_rdoc_files: []
57
+ files:
58
+ - .gitignore
59
+ - Gemfile
60
+ - README.md
61
+ - Rakefile
62
+ - lib/utopia/extras.rb
63
+ - lib/utopia/extras/version.rb
64
+ - lib/utopia/middleware/benchmark.rb
65
+ - lib/utopia/middleware/filter.rb
66
+ - lib/utopia/tags/fortune.rb
67
+ - lib/utopia/tags/gallery.rb
68
+ - lib/utopia/tags/google_analytics.rb
69
+ - utopia-extras.gemspec
70
+ homepage: ''
71
+ licenses: []
72
+ post_install_message:
73
+ rdoc_options: []
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ none: false
78
+ requirements:
79
+ - - ! '>='
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ requirements: []
89
+ rubyforge_project:
90
+ rubygems_version: 1.8.24
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: A collection of useful extras for the Utopia framework.
94
+ test_files: []