multigiri 0.0.1

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,12 @@
1
+ *~
2
+ .*.swp
3
+ .#*
4
+
5
+ .DS_Store
6
+ .cache
7
+ .yardoc
8
+
9
+ /*.gem
10
+ script/*
11
+ gems/*
12
+ !gems/cache
data/CHANGELOG ADDED
@@ -0,0 +1,2 @@
1
+ = Version 0.0.1
2
+ * Initial import
data/Gemfile ADDED
@@ -0,0 +1,9 @@
1
+ # gems
2
+ gem "nake"
3
+ gem "rspec"
4
+ gem "code-cleaner"
5
+ gem "nokogiri"
6
+
7
+ # settings
8
+ bin_path "script"
9
+ bundle_path "gems"
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2010 Jakub Stastny aka Botanicus
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.textile ADDED
@@ -0,0 +1,21 @@
1
+ h1. About
2
+
3
+ h1. Usage
4
+
5
+ Take a look at an "example":http://github.com/botanicus/multigiri/blob/master/examples/config.ru. The point is:
6
+
7
+ <pre>
8
+ use Multigiri do
9
+ use HTML5::Forms
10
+ use HTML5::Hidden
11
+ use EmailObfuscator
12
+ use GoogleAnalytics, :my_tracking_code
13
+ end
14
+ </pre>
15
+
16
+ h1. Links
17
+
18
+ * "Source Code":http://github.com/botanicus/multigiri
19
+ * "Wiki":http://wiki.github.com/botanicus/multigiri
20
+ * "API Docs":http://rdoc.info/projects/botanicus/multigiri
21
+ * "Bug reporting":http://github.com/botanicus/multigiri/issues
data/TODO.txt ADDED
File without changes
data/deps.rip ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env rip install
2
+
3
+ # Syntax:
4
+ # repository [tag or commit to install]
5
+ git://github.com/tenderlove/nokogiri.git
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env rackup -p 4000 -s thin
2
+
3
+ $:.unshift(::File.expand_path("../../lib", __FILE__))
4
+
5
+ require "multigiri"
6
+ require "multigiri/html5"
7
+ require "multigiri/email_obfuscator"
8
+ require "multigiri/google_analytics"
9
+
10
+ # Multigiri change the last element of the rack array from body to
11
+ # nokogiri, document so instead of [status, headers, body] you'll get
12
+ # [status, headers, document]. After the multigiri block everything
13
+ # will get to normal, so middlewares whichrun later won't be affected.
14
+ use Multigiri do
15
+ use HTML5::Forms
16
+ use HTML5::Hidden
17
+ use EmailObfuscator
18
+ use GoogleAnalytics, :my_tracking_code
19
+ end
20
+
21
+ # It's especially important to run these middlewares after multigiri,
22
+ # because in multigiri middleware you probably change the resulted HTML
23
+ use ContentType
24
+ use ContentLength
25
+
26
+ # We can't use the trick with __END__ as is used in sinatra, since Rack
27
+ # authors are stupid idiots and the content of the rackup file is eval-ed.
28
+ # This crappy design leads to more problems than just this one.
29
+ # template = ::File.read(__FILE__).split("__END__").last
30
+
31
+ template = ::File.read(__FILE__).match(/=begin template\n(.+)\n=end/m)[1]
32
+
33
+ run lambda { |env| [200, Hash.new, [template]] }
34
+
35
+ =begin template
36
+ <html>
37
+ <body>
38
+ <h1>Hello World!</h1>
39
+ <a href='joe@example.com'>mail</a>
40
+ <p hidden>test</p>
41
+ <p hidden style="color:red">test</p>
42
+ <form method="GET">
43
+ </form>
44
+ <form method="PUT">
45
+ </form>
46
+ <form method="DELETE">
47
+ </form>
48
+ </body>
49
+ </html>
50
+ =end
File without changes
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ module Rack
4
+ class Multigiri
5
+ class EmailObfuscator
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ status, headers, document = @app.call(env)
12
+ # document.css("a[href~='@']").each do |element|
13
+ document.css("a[href]").each do |element|
14
+ element[:href] = element[:href].sub("@", "&#x40;")
15
+ end
16
+ [status, headers, document]
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,53 @@
1
+ # encoding: utf-8
2
+
3
+ # Add Google Analytics tracking to your page
4
+
5
+ # @example
6
+ # use Multigiri do
7
+ # use GoogleAnalytics, :my_tracking_code if Rango.production?
8
+ # end
9
+
10
+ module Rack
11
+ class Multigiri
12
+ class GoogleAnalytics
13
+ attr_accessor :tracking_code
14
+ def initialize(app, tracking_code)
15
+ @app, @tracking_code = app, tracking_code
16
+ end
17
+
18
+ def call(env)
19
+ status, headers, document = @app.call(env)
20
+ body = document.xpath("/html/body")[0]
21
+
22
+ # include scripts to the page
23
+ script(body, protocol_recognition_script)
24
+ script(body, tracker_script)
25
+
26
+ [status, headers, document]
27
+ end
28
+
29
+ protected
30
+ def script(body, content)
31
+ script = Nokogiri::XML::Node.new(:script, body.document)
32
+ script.inner_html = content
33
+ body.add_child(script)
34
+ end
35
+
36
+ def protocol_recognition_script
37
+ <<-EOF
38
+ var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
39
+ document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
40
+ EOF
41
+ end
42
+
43
+ def tracker_script
44
+ <<-EOF
45
+ try {
46
+ var pageTracker = _gat._getTracker("#{self.tracking_code}");
47
+ pageTracker._trackPageview();
48
+ } catch(err) {}
49
+ EOF
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,46 @@
1
+ # encoding: utf-8
2
+
3
+ module Rack
4
+ class Multigiri
5
+ module HTML5
6
+ class Forms
7
+ def initialize(app)
8
+ @app = app
9
+ end
10
+
11
+ def call(env)
12
+ status, headers, document = @app.call(env)
13
+ nodes = document.css("form[method=PUT]") + document.css("form[method=DELETE]")
14
+ nodes.each do |form|
15
+ input = Nokogiri::XML::Node.new("input", document)
16
+ input[:type] = "hidden"
17
+ input[:name] = "_method"
18
+ input[:value] = form[:method]
19
+ form[:method] = "POST"
20
+ form.add_child(input)
21
+ end
22
+ [status, headers, document]
23
+ end
24
+ end
25
+
26
+ class Hidden
27
+ def initialize(app)
28
+ @app = app
29
+ end
30
+
31
+ def call(env)
32
+ status, headers, document = @app.call(env)
33
+ document.css("[hidden]").each do |element|
34
+ element.remove_attribute("hidden")
35
+ if element[:style]
36
+ element[:style] += "; display: none"
37
+ else
38
+ element[:style] = "display:none"
39
+ end
40
+ end
41
+ [status, headers, document]
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module Rack
4
+ class Multigiri
5
+ VERSION = "0.0.1"
6
+ end
7
+ end
data/lib/multigiri.rb ADDED
@@ -0,0 +1,43 @@
1
+ # encoding: utf-8
2
+
3
+ # use Multigiri do
4
+ # use GoogleAnalytics, :my_tracking_code
5
+ # use EmailObfuscator
6
+ # use HTML5::Forms
7
+ # use HTML5::Hidden
8
+ # end
9
+
10
+ require "nokogiri"
11
+
12
+ # TODO: args for nokogiri, export format, indentation etc
13
+ module Rack
14
+ class Multigiri
15
+ def initialize(app, &block)
16
+ @app, @block = app, block
17
+ end
18
+
19
+ def call(env)
20
+ # convert to a Nokogiri document
21
+ status, headers, chunks = @app.call(env)
22
+ # the only what we know about body is that it has to respond to #each
23
+ body = String.new
24
+ chunks.each { |chunk| body += chunk }
25
+ document = Nokogiri::HTML(body) # before
26
+ @stack = lambda { |env| [status, headers, document] }
27
+
28
+ # get middlewares
29
+ self.instance_eval(&@block) if @block
30
+
31
+ # convert back to a [String]
32
+ status, headers, document = @stack.call(env)
33
+ body = document.to_html(indentation: 2) # TODO
34
+ headers["Content-Length"] = body.length.to_s
35
+ [status, headers, [body]]
36
+ end
37
+
38
+ # GoogleAnalytics.new(Other.new(self), tracking_code)
39
+ def use(klass, *args, &block)
40
+ @stack = klass.new(@stack, *args, &block)
41
+ end
42
+ end
43
+ end
data/multigiri.gemspec ADDED
@@ -0,0 +1,43 @@
1
+ #!/usr/bin/env gem build
2
+ # encoding: utf-8
3
+
4
+ # Run ./multigiri.gemspec or gem build multigiri.gemspec
5
+ # NOTE: we can't use require_relative because when we run gem build, it use eval for executing this file
6
+ require File.join(File.dirname(__FILE__), "lib", "multigiri", "version")
7
+ require "base64"
8
+
9
+ Gem::Specification.new do |s|
10
+ s.name = "multigiri"
11
+ s.version = Rack::Multigiri::VERSION
12
+ s.authors = ["Jakub Stastny aka Botanicus"]
13
+ s.homepage = "http://github.com/botanicus/multigiri"
14
+ s.summary = "" # TODO: summary
15
+ s.description = "" # TODO: long description
16
+ s.cert_chain = nil
17
+ s.email = Base64.decode64("c3Rhc3RueUAxMDFpZGVhcy5jeg==\n")
18
+ s.has_rdoc = true
19
+
20
+ # files
21
+ s.files = `git ls-files`.split("\n")
22
+
23
+ s.executables = Dir["bin/*"].map(&File.method(:basename))
24
+ s.default_executable = "multigiri"
25
+ s.require_paths = ["lib"]
26
+
27
+ # Ruby version
28
+ s.required_ruby_version = ::Gem::Requirement.new(">= 1.9")
29
+
30
+ # runtime dependencies
31
+ s.add_dependency "nokogiri"
32
+
33
+ begin
34
+ require "changelog"
35
+ rescue LoadError
36
+ warn "You have to have changelog gem installed for post install message"
37
+ else
38
+ s.post_install_message = CHANGELOG.new.version_changes
39
+ end
40
+
41
+ # RubyForge
42
+ s.rubyforge_project = "multigiri"
43
+ end
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env gem build
2
+ # encoding: utf-8
3
+
4
+ # You might think this is a terrible mess and guess what, you're
5
+ # right mate! However say thanks to authors of RubyGems, not me.
6
+ eval(File.read("multigiri.gemspec")).tap do |specification|
7
+ specification.version = "#{specification.version}.pre"
8
+ end
File without changes
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "spec_helper"
4
+
5
+ describe Multigiri do
6
+ it "should have VERSION constant" do
7
+ Multigiri::VERSION.should be_kind_of(String)
8
+ Multigiri::VERSION.should match(/^\d+\.\d+\.\d+$/)
9
+ end
10
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1,5 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ # dependencies
4
+ require "spec"
5
+
6
+ # setup load paths
7
+ $:.unshift(File.expand_path("../lib"), __FILE__)
data/tasks.rb ADDED
@@ -0,0 +1,37 @@
1
+ #!./script/nake
2
+ # encoding: utf-8
3
+
4
+ begin
5
+ require_relative "gems/environment.rb"
6
+ rescue LoadError
7
+ abort "You have to install bundler and run gem bundle first!"
8
+ end
9
+
10
+ ENV["PATH"] = "script:#{ENV["PATH"]}"
11
+
12
+ require "nake/tasks/gem"
13
+ require "nake/tasks/spec"
14
+ require "nake/tasks/release"
15
+
16
+ require_relative "lib/multigiri/version"
17
+
18
+ begin
19
+ load "code-cleaner.nake"
20
+ Nake::Task["hooks:whitespace:install"].tap do |task|
21
+ task.config[:path] = "script"
22
+ task.config[:encoding] = "utf-8"
23
+ task.config[:whitelist] = '(bin/[^/]+|.+\.(rb|rake|nake|thor|task))$'
24
+ end
25
+ rescue LoadError
26
+ warn "If you want to contribute to Multigiri, please install code-cleaner and then run ./tasks.rb hooks:whitespace:install to get Git pre-commit hook for removing trailing whitespace."
27
+ end
28
+
29
+ # Setup encoding, so all the operations
30
+ # with strings from another files will work
31
+ Encoding.default_internal = "utf-8"
32
+ Encoding.default_external = "utf-8"
33
+
34
+ Task[:build].config[:gemspec] = "multigiri.gemspec"
35
+ Task[:prerelease].config[:gemspec] = "multigiri.pre.gemspec"
36
+ Task[:release].config[:name] = "multigiri"
37
+ Task[:release].config[:version] = Multigiri::VERSION
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: multigiri
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Jakub Stastny aka Botanicus
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain:
11
+ date: 2010-02-03 00:00:00 +00:00
12
+ default_executable: multigiri
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: nokogiri
16
+ type: :runtime
17
+ version_requirement:
18
+ version_requirements: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: "0"
23
+ version:
24
+ description: ""
25
+ email: stastny@101ideas.cz
26
+ executables: []
27
+
28
+ extensions: []
29
+
30
+ extra_rdoc_files: []
31
+
32
+ files:
33
+ - .gitignore
34
+ - CHANGELOG
35
+ - Gemfile
36
+ - LICENSE
37
+ - README.textile
38
+ - TODO.txt
39
+ - deps.rip
40
+ - examples/config.ru
41
+ - lib/multigiri.rb
42
+ - lib/multigiri/.gitignore
43
+ - lib/multigiri/email_obfuscator.rb
44
+ - lib/multigiri/google_analytics.rb
45
+ - lib/multigiri/html5.rb
46
+ - lib/multigiri/version.rb
47
+ - multigiri.gemspec
48
+ - multigiri.pre.gemspec
49
+ - spec/multigiri/.gitignore
50
+ - spec/multigiri_spec.rb
51
+ - spec/spec.opts
52
+ - spec/spec_helper.rb
53
+ - tasks.rb
54
+ has_rdoc: true
55
+ homepage: http://github.com/botanicus/multigiri
56
+ licenses: []
57
+
58
+ post_install_message: "[\e[32mVersion 0.0.1\e[0m] Initial import\n"
59
+ rdoc_options: []
60
+
61
+ require_paths:
62
+ - lib
63
+ required_ruby_version: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ version: "1.9"
68
+ version:
69
+ required_rubygems_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ requirements: []
76
+
77
+ rubyforge_project: multigiri
78
+ rubygems_version: 1.3.5
79
+ signing_key:
80
+ specification_version: 3
81
+ summary: ""
82
+ test_files: []
83
+