multigiri 0.0.2 → 0.0.3
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/CHANGELOG +4 -0
- data/lib/multigiri/default_attributes.rb +22 -0
- data/lib/multigiri/email_obfuscator.rb +11 -13
- data/lib/multigiri/google_analytics.rb +32 -34
- data/lib/multigiri/html5.rb +33 -35
- data/lib/multigiri/link_checker.rb +40 -31
- data/lib/multigiri/minify.rb +15 -0
- data/lib/multigiri/version.rb +2 -4
- data/lib/multigiri.rb +24 -25
- data/multigiri.gemspec +2 -2
- metadata +7 -5
- data/lib/multigiri/.gitignore +0 -0
data/CHANGELOG
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class Multigiri
|
4
|
+
class DefaultAttributes
|
5
|
+
def initialize(app, defaults = nil)
|
6
|
+
@app, @defaults = app, defaults
|
7
|
+
@defaults ||= {"form" => {"method" => "POST"}, "script" => {"type" => "text/javascript"}}
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
status, headers, document = @app.call(env)
|
12
|
+
@defaults.each do |tag, attributes|
|
13
|
+
document.css(tag).each do |element|
|
14
|
+
attributes.each do |attribute, value|
|
15
|
+
element[attribute] ||= value
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
[status, headers, document]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -1,20 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
class
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
3
|
+
class Multigiri
|
4
|
+
class EmailObfuscator
|
5
|
+
def initialize(app)
|
6
|
+
@app = app
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
[status, headers, document]
|
9
|
+
def call(env)
|
10
|
+
status, headers, document = @app.call(env)
|
11
|
+
# document.css("a[href~='@']").each do |element|
|
12
|
+
document.css("a[href]").each do |element|
|
13
|
+
element["href"] = element["href"].sub("@", "@")
|
17
14
|
end
|
15
|
+
[status, headers, document]
|
18
16
|
end
|
19
17
|
end
|
20
18
|
end
|
@@ -7,47 +7,45 @@
|
|
7
7
|
# use GoogleAnalytics, :my_tracking_code if Rango.production?
|
8
8
|
# end
|
9
9
|
|
10
|
-
|
11
|
-
class
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
<<-EOF
|
10
|
+
class Multigiri
|
11
|
+
class GoogleAnalytics
|
12
|
+
attr_accessor :tracking_code
|
13
|
+
def initialize(app, tracking_code)
|
14
|
+
@app, @tracking_code = app, tracking_code
|
15
|
+
end
|
16
|
+
|
17
|
+
def call(env)
|
18
|
+
status, headers, document = @app.call(env)
|
19
|
+
body = document.xpath("/html/body")[0]
|
20
|
+
|
21
|
+
# include scripts to the page
|
22
|
+
script(body, protocol_recognition_script)
|
23
|
+
script(body, tracker_script)
|
24
|
+
|
25
|
+
[status, headers, document]
|
26
|
+
end
|
27
|
+
|
28
|
+
protected
|
29
|
+
def script(body, content)
|
30
|
+
script = Nokogiri::XML::Node.new(:script, body.document)
|
31
|
+
script.inner_html = content
|
32
|
+
body.add_child(script)
|
33
|
+
end
|
34
|
+
|
35
|
+
def protocol_recognition_script
|
36
|
+
<<-EOF
|
38
37
|
var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
|
39
38
|
document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
|
40
|
-
|
41
|
-
|
39
|
+
EOF
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
42
|
+
def tracker_script
|
43
|
+
<<-EOF
|
45
44
|
try {
|
46
45
|
var pageTracker = _gat._getTracker("#{self.tracking_code}");
|
47
46
|
pageTracker._trackPageview();
|
48
47
|
} catch(err) {}
|
49
|
-
|
50
|
-
end
|
48
|
+
EOF
|
51
49
|
end
|
52
50
|
end
|
53
51
|
end
|
data/lib/multigiri/html5.rb
CHANGED
@@ -4,48 +4,46 @@
|
|
4
4
|
|
5
5
|
# In future it can detect if the browser is capable to deal with given HTML 5 feature and
|
6
6
|
# if yes, then there will be no transformation required. But then carefully with caching :)
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
end
|
7
|
+
class Multigiri
|
8
|
+
module HTML5
|
9
|
+
# Browsers supporting HTML 5 should can submit forms through PUT or DELETE natively.
|
10
|
+
class Forms
|
11
|
+
def initialize(app)
|
12
|
+
@app = app
|
13
|
+
end
|
15
14
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end
|
27
|
-
[status, headers, document]
|
15
|
+
def call(env)
|
16
|
+
status, headers, document = @app.call(env)
|
17
|
+
nodes = document.css("form[method=PUT]") + document.css("form[method=DELETE]")
|
18
|
+
nodes.each do |form|
|
19
|
+
input = Nokogiri::XML::Node.new("input", document)
|
20
|
+
input["type"] = "hidden"
|
21
|
+
input["name"] = "_method"
|
22
|
+
input["value"] = form["method"]
|
23
|
+
form["method"] = "POST"
|
24
|
+
form.add_child(input)
|
28
25
|
end
|
26
|
+
[status, headers, document]
|
29
27
|
end
|
28
|
+
end
|
30
29
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
30
|
+
# Elements can have attribute hidden.
|
31
|
+
class Hidden
|
32
|
+
def initialize(app)
|
33
|
+
@app = app
|
34
|
+
end
|
36
35
|
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
36
|
+
def call(env)
|
37
|
+
status, headers, document = @app.call(env)
|
38
|
+
document.css("[hidden]").each do |element|
|
39
|
+
element.remove_attribute("hidden")
|
40
|
+
if element["style"]
|
41
|
+
element["style"] += "; display: none"
|
42
|
+
else
|
43
|
+
element["style"] = "display:none"
|
46
44
|
end
|
47
|
-
[status, headers, document]
|
48
45
|
end
|
46
|
+
[status, headers, document]
|
49
47
|
end
|
50
48
|
end
|
51
49
|
end
|
@@ -2,45 +2,54 @@
|
|
2
2
|
|
3
3
|
# @example
|
4
4
|
# use Multigiri do
|
5
|
-
# use LinkChecker,
|
6
|
-
#
|
5
|
+
# use LinkChecker, Logger.new("log/links.log") do |checker|
|
6
|
+
# def checker.path_from_link(link)
|
7
|
+
# "media" + link
|
8
|
+
# end
|
7
9
|
# end
|
8
10
|
# end
|
9
|
-
|
10
|
-
class
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
def links
|
18
|
-
@links ||= Array.new
|
19
|
-
end
|
11
|
+
class Multigiri
|
12
|
+
class LinkChecker
|
13
|
+
def initialize(app, logger, patterns = nil, &block)
|
14
|
+
@app, @logger, @patterns = app, logger, patterns
|
15
|
+
@patterns ||= {"img" => "src", "link" => "href", "a" => "href"}
|
16
|
+
block.call(self) unless block.nil?
|
17
|
+
end
|
20
18
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
19
|
+
def call(env)
|
20
|
+
@path_info = env["PATH_INFO"]
|
21
|
+
status, headers, document = @app.call(env)
|
22
|
+
@patterns.each do |tag, attribute|
|
23
|
+
document.css("#{tag}[#{attribute}]").each do |element|
|
24
|
+
link = element[attribute]
|
25
|
+
if link.match(/^\w+:\/\//)
|
26
|
+
check_remote_link(link)
|
27
|
+
else
|
28
|
+
check_local_link(link)
|
29
29
|
end
|
30
30
|
end
|
31
|
-
check_links
|
32
|
-
[status, headers, document]
|
33
31
|
end
|
32
|
+
[status, headers, document]
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
35
|
+
private
|
36
|
+
def path_from_link(link)
|
37
|
+
"public" + link
|
38
|
+
end
|
39
|
+
|
40
|
+
def check_local_link(link)
|
41
|
+
real_path = path_from_link(link)
|
42
|
+
unless File.exist?(real_path)
|
43
|
+
@logger.error("[LINK from #{@path_info}] #{link} doesn't exist in #{real_path}")
|
43
44
|
end
|
44
45
|
end
|
46
|
+
|
47
|
+
def check_remote_link(link)
|
48
|
+
# require "net/http"
|
49
|
+
#
|
50
|
+
# Net::HTTP::Get.start() do |http|
|
51
|
+
# http
|
52
|
+
# end
|
53
|
+
end
|
45
54
|
end
|
46
55
|
end
|
data/lib/multigiri/version.rb
CHANGED
data/lib/multigiri.rb
CHANGED
@@ -10,34 +10,33 @@
|
|
10
10
|
require "nokogiri"
|
11
11
|
|
12
12
|
# TODO: args for nokogiri, export format, indentation etc
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
13
|
+
class Multigiri
|
14
|
+
def initialize(app, options = Hash.new, &block)
|
15
|
+
@app, @options, @block = app, options, block
|
16
|
+
@options[:indentation] ||= 2
|
17
|
+
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
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
27
|
|
28
|
-
|
29
|
-
|
28
|
+
# get middlewares
|
29
|
+
self.instance_eval(&@block) if @block
|
30
30
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
31
|
+
# convert back to a [String]
|
32
|
+
status, headers, document = @stack.call(env)
|
33
|
+
body = document.to_html(indentation: options[:indentation]) # TODO
|
34
|
+
headers["Content-Length"] = body.bytesize.to_s
|
35
|
+
[status, headers, [body]]
|
36
|
+
end
|
37
37
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
end
|
38
|
+
# GoogleAnalytics.new(Other.new(self), tracking_code)
|
39
|
+
def use(klass, *args, &block)
|
40
|
+
@stack = klass.new(@stack, *args, &block)
|
42
41
|
end
|
43
42
|
end
|
data/multigiri.gemspec
CHANGED
@@ -3,12 +3,12 @@
|
|
3
3
|
|
4
4
|
# Run ./multigiri.gemspec or gem build multigiri.gemspec
|
5
5
|
# NOTE: we can't use require_relative because when we run gem build, it use eval for executing this file
|
6
|
-
require File.
|
6
|
+
require File.expand_path("../lib/multigiri/version", __FILE__)
|
7
7
|
require "base64"
|
8
8
|
|
9
9
|
Gem::Specification.new do |s|
|
10
10
|
s.name = "multigiri"
|
11
|
-
s.version =
|
11
|
+
s.version = Multigiri::VERSION
|
12
12
|
s.authors = ["Jakub Stastny aka Botanicus"]
|
13
13
|
s.homepage = "http://github.com/botanicus/multigiri"
|
14
14
|
s.summary = "" # TODO: summary
|
metadata
CHANGED
@@ -5,15 +5,15 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 0
|
8
|
-
-
|
9
|
-
version: 0.0.
|
8
|
+
- 3
|
9
|
+
version: 0.0.3
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Jakub Stastny aka Botanicus
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain:
|
16
|
-
date: 2010-03-
|
16
|
+
date: 2010-03-13 00:00:00 +00:00
|
17
17
|
default_executable: multigiri
|
18
18
|
dependencies:
|
19
19
|
- !ruby/object:Gem::Dependency
|
@@ -46,11 +46,12 @@ files:
|
|
46
46
|
- deps.rip
|
47
47
|
- examples/config.ru
|
48
48
|
- lib/multigiri.rb
|
49
|
-
- lib/multigiri
|
49
|
+
- lib/multigiri/default_attributes.rb
|
50
50
|
- lib/multigiri/email_obfuscator.rb
|
51
51
|
- lib/multigiri/google_analytics.rb
|
52
52
|
- lib/multigiri/html5.rb
|
53
53
|
- lib/multigiri/link_checker.rb
|
54
|
+
- lib/multigiri/minify.rb
|
54
55
|
- lib/multigiri/version.rb
|
55
56
|
- multigiri.gemspec
|
56
57
|
- multigiri.pre.gemspec
|
@@ -63,7 +64,8 @@ has_rdoc: true
|
|
63
64
|
homepage: http://github.com/botanicus/multigiri
|
64
65
|
licenses: []
|
65
66
|
|
66
|
-
post_install_message: "[\e[32mVersion 0.0.
|
67
|
+
post_install_message: "[\e[32mVersion 0.0.2\e[0m] Added link checker for checking if local links are valid\n\
|
68
|
+
[\e[32mVersion 0.0.2\e[0m] Added middleware for setting default attributes for tags\n"
|
67
69
|
rdoc_options: []
|
68
70
|
|
69
71
|
require_paths:
|
data/lib/multigiri/.gitignore
DELETED
File without changes
|