multigiri 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+