merb_footnotes 0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,16 @@
1
+ require "#{File.dirname(__FILE__)}/files_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class JavascriptsNote < FilesNote
6
+ def title
7
+ "Javascripts (#{@files.length})"
8
+ end
9
+
10
+ protected
11
+ def scan_text(text)
12
+ text.scan(/<script[^>]+src\s*=\s*['"]([^>?'"]+\.js)/im).flatten
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,33 @@
1
+ # LAYOUT NOTE
2
+ # Todo: make this note display the currently displayed layout
3
+
4
+ require "#{File.dirname(__FILE__)}/view_note"
5
+
6
+ module MerbFootnotes
7
+ module Notes
8
+ class LayoutNote < AbstractNote
9
+ def initialize(controller)
10
+ @controller = controller
11
+ @layout_path = find_layout
12
+ end
13
+
14
+ def row
15
+ :edit
16
+ end
17
+
18
+ def link
19
+ escape(Merb::Plugins.config[:merb_footnotes][:prefix] + @layout_path)
20
+ end
21
+
22
+ def valid?
23
+ prefix? and !@layout_path.blank?
24
+ end
25
+
26
+ protected
27
+ def find_layout
28
+ # TODO: find the real rendered layout
29
+ "#{Merb.root}/app/views/layout/application.html.#{Merb.template_engine}"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,38 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class LogNote < AbstractNote
6
+ def initialize(controller)
7
+ @controller = controller
8
+ end
9
+
10
+ def content
11
+ ""
12
+ # TODO
13
+ # escape(log_tail).gsub("\n","<br />")
14
+ end
15
+
16
+ protected
17
+ def log_tail
18
+ filename = if Merb.logger.instance_variable_get('@log')
19
+ Merb.logger.instance_variable_get('@log').path
20
+ else
21
+ Merb.logger.instance_variable_get('@logdev').filename
22
+ end
23
+ file_string = File.open(filename).read.to_s
24
+
25
+ # We try to select the specified action from the log
26
+ # If we can't find it, we get the last 100 lines
27
+ #
28
+ if rindex = file_string.rindex('Processing '+@controller.controller_class_name+'#'+@controller.action_name)
29
+ file_string[rindex..-1].gsub(/\e\[.+?m/, '')
30
+ else
31
+ lines = file_string.split("\n")
32
+ index = [lines.size-100,0].max
33
+ lines[index..-1].join("\n")
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,19 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class ParamsNote < AbstractNote
6
+ def initialize(controller)
7
+ @params = controller.params
8
+ end
9
+
10
+ def title
11
+ "Params (#{@params.length})"
12
+ end
13
+
14
+ def content
15
+ escape(@params.inspect)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,59 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ # View Note
4
+ # this note should give you an easy linkback to the currently render view
5
+ # TODO: include all rendered partials by wrapping the partial call
6
+ module MerbFootnotes
7
+ module Notes
8
+ class PartialsNote < AbstractNote
9
+ def initialize(controller)
10
+ @controller = controller
11
+ @partials = format_partials(@controller.footnotes[:partials])
12
+ end
13
+
14
+ def row
15
+ :edit
16
+ end
17
+
18
+ def title
19
+ "Partials (#{@partials.size})"
20
+ end
21
+
22
+ # def link
23
+ # escape(Merb::Plugins.config[:merb_footnotes][:prefix] + filename)
24
+ # end
25
+
26
+ def content
27
+ mount_table(@partials.unshift([:partial, :arguments]))
28
+ end
29
+
30
+ def valid?
31
+ prefix?
32
+ end
33
+
34
+ protected
35
+ def format_partials(partials)
36
+ display_list = []
37
+ partials.each do |r|
38
+ action = r.first
39
+ opts = r.last
40
+
41
+ action = "<a href='#{get_path_for_partial(action)}'>#{action}</a>"
42
+ display_list << [action.to_s, opts.inspect]
43
+ end
44
+ display_list
45
+ end
46
+
47
+ def get_path_for_partial(template)
48
+ template = template.to_s
49
+ if template =~ %r{^/}
50
+ template_path = File.dirname(template) / "_#{File.basename(template)}"
51
+ else
52
+ kontroller = (m = template.match(/.*(?=\/)/)) ? m[0] : @controller.controller_name
53
+ template_path = "#{kontroller}/_#{File.basename(template)}"
54
+ end
55
+ "#{Merb::Plugins.config[:merb_footnotes][:prefix]}/#{Merb.root}/app/views/#{template_path}.html.#{Merb.template_engine}"
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,139 @@
1
+ # TODO: fix instrumentation in order to populate the MerbFootNotes::Notes::QueriesNote.sql accessor
2
+
3
+ require "#{File.dirname(__FILE__)}/abstract_note"
4
+
5
+ module MerbFootnotes
6
+ module Notes
7
+ class QueriesNote < AbstractNote
8
+ @@sql = []
9
+
10
+ def self.sql
11
+ @@sql
12
+ end
13
+
14
+ def self.start!(controller)
15
+ @@sql = []
16
+ end
17
+
18
+ def self.to_sym
19
+ :queries
20
+ end
21
+
22
+ def title
23
+ "Queries (#{@@sql.length})"
24
+ end
25
+
26
+ def stylesheet
27
+ %{
28
+ #queries_debug_info table td, #queries_debug_info table th{border:1px solid #A00; padding:0 3px; text-align:center;}
29
+ #queries_debug_info table thead, #queries_debug_info table tbody {color:#A00;}
30
+ #queries_debug_info p {background-color:#F3F3FF; border:1px solid #CCC; margin:12px; padding:4px 6px;}
31
+ #queries_debug_info a:hover {text-decoration:underline;}
32
+ }
33
+ end
34
+
35
+ def javascript
36
+ %{
37
+ function queries_toogle(type, id){
38
+ s = document.getElementById('q'+type+'_'+id).style
39
+ s.display = (s.display != 'block') ? 'block' : 'none'
40
+ location.href = '#qtitle_'+id
41
+ }
42
+ }
43
+ end
44
+
45
+ def content
46
+ html = ''
47
+
48
+ @@sql.each_with_index do |item, i|
49
+ sql_links = []
50
+ sql_links << "<a href=\"#\" style=\"color:#A00;\" onclick=\"queries_toogle('table',#{i});return false\">explain</a>" if item.explain
51
+ sql_links << "<a href=\"#\" style=\"color:#00A;\" onclick=\"queries_toogle('trace',#{i});return false\">trace</a>" if item.trace
52
+
53
+ html << %{
54
+ <b id="qtitle_#{i}">#{escape(item.type.to_s.upcase)}</b> (#{sql_links.join(' | ')})<br />
55
+ #{print_name_and_time(item.name, item.time)}<br />
56
+ #{print_query(item.query)}<br />
57
+ #{print_explain(i, item.explain) if item.explain}
58
+ <p id="qtrace_#{i}" style="display:none;">#{parse_trace(item.trace) if item.trace}</p><br />
59
+ }
60
+ end
61
+
62
+ # return html
63
+
64
+ # TODO: remove this
65
+ return "NOT WORKING"
66
+
67
+ end
68
+
69
+ protected
70
+ def parse_explain(results)
71
+ table = []
72
+ table << results.fetch_fields.map{|f| f.name}
73
+ results.each{|row| table << row}
74
+ table
75
+ end
76
+
77
+ def parse_trace(trace)
78
+ trace.map do |t|
79
+ s = t.split(':')
80
+ "<a href=\"#{escape("#{Merb::Plugins.config[:merb_footnotes][:prefix]}#{Merb.root}/#{s[0]}&line=#{s[1].to_i}")}\">#{escape(t)}</a><br />"
81
+ end.join
82
+ end
83
+
84
+ def print_name_and_time(name, time)
85
+ "#{escape(name || 'SQL')} (#{sprintf('%f', time)}s)"
86
+ end
87
+
88
+ def print_query(query)
89
+ escape(query.to_s.gsub(/(\s)+/, ' ').gsub('`', ''))
90
+ end
91
+
92
+ def print_explain(i, explain)
93
+ mount_table(parse_explain(explain), :id => "qtable_#{i}", :style => 'margin:10px;display:none;')
94
+ end
95
+ end
96
+ end
97
+
98
+ module Extensions
99
+ class Sql
100
+ attr_accessor :type, :name, :time, :query, :explain, :trace
101
+
102
+ def initialize(type, name, time, query, explain)
103
+ @type = type
104
+ @name = name
105
+ @time = time
106
+ @query = query
107
+ @explain = explain
108
+
109
+ # Strip, select those ones from app and reject first two, because they are from the plugin
110
+ @trace = Kernel.caller.collect{|c| c.strip}.select{|i| i.gsub!(/^#{Merb.root}\//im, '') }[2..-1]
111
+ end
112
+ end
113
+
114
+ module AbstractAdapter
115
+ def log_silence
116
+ result = nil
117
+ if @logger
118
+ @logger.silence do
119
+ result = yield
120
+ end
121
+ else
122
+ result = yield
123
+ end
124
+ result
125
+ end
126
+ end
127
+ end
128
+ end
129
+
130
+ # NOT WORKING
131
+
132
+ # if MerbFootnotes::Notes::QueriesNote.included?
133
+ # ActiveRecord::ConnectionAdapters::AbstractAdapter.__send__ :include, MerbFootnotes::Extensions::AbstractAdapter
134
+ # ActiveRecord::ConnectionAdapters.local_constants.each do |adapter|
135
+ # next unless adapter =~ /.*[^Abstract]Adapter$/
136
+ # next if adapter =~ /SQLite.Adapter$/
137
+ # eval("ActiveRecord::ConnectionAdapters::#{adapter}").__send__ :include, MerbFootnotes::Extensions::QueryAnalyzer
138
+ # end
139
+ # end
@@ -0,0 +1,35 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class RoutesNote < AbstractNote
6
+ def initialize(controller)
7
+ @controller = controller
8
+ @parsed_routes = parse_routes || []
9
+ end
10
+
11
+ def legend
12
+ "Routes for #{@controller.class.to_s}"
13
+ end
14
+
15
+ def content
16
+ mount_table(@parsed_routes.to_a.unshift([:name, :path, :params]))
17
+ end
18
+
19
+ protected
20
+ def parse_routes
21
+ routes_with_name = Merb::Router.named_routes.to_a
22
+
23
+ return Merb::Router.routes.collect do |route|
24
+ if route.params[:controller].to_s.include?(@controller.class.to_s.downcase)
25
+ [
26
+ escape(route.name.to_s),
27
+ route.segments.to_a.join,
28
+ route.params.reject{|key, value| key == :controller}.inspect.gsub('\"', '')
29
+ ]
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,19 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class SessionNote < AbstractNote
6
+ def initialize(controller)
7
+ @session = controller.session
8
+ end
9
+
10
+ def title
11
+ "Session (#{@session.size})"
12
+ end
13
+
14
+ def content
15
+ escape(@session.inspect)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,16 @@
1
+ require "#{File.dirname(__FILE__)}/files_note"
2
+
3
+ module MerbFootnotes
4
+ module Notes
5
+ class StylesheetsNote < FilesNote
6
+ def title
7
+ "Stylesheets (#{@files.length})"
8
+ end
9
+
10
+ protected
11
+ def scan_text(text)
12
+ text.scan(/<link[^>]+href\s*=\s*['"]([^>?'"]+\.css)/im).flatten
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,37 @@
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ # View Note
4
+ # this note should give you an easy linkback to the currently render view
5
+ # TODO: include all rendered partials by wrapping the partial call
6
+ module MerbFootnotes
7
+ module Notes
8
+ class ViewNote < AbstractNote
9
+ def initialize(controller)
10
+ @controller = controller
11
+ @filename = get_filename
12
+ end
13
+
14
+ def row
15
+ :edit
16
+ end
17
+
18
+ def title
19
+ "View"
20
+ end
21
+
22
+ def link
23
+ escape(Merb::Plugins.config[:merb_footnotes][:prefix] + @filename)
24
+ end
25
+
26
+
27
+ def valid?
28
+ prefix?
29
+ end
30
+
31
+ protected
32
+ def get_filename
33
+ "#{Merb.root}/app/views/#{@controller.controller_name}/#{@controller.params[:action]}.html.#{Merb.template_engine}"
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,7 @@
1
+ require File.dirname(__FILE__) + '/spec_helper'
2
+
3
+ describe "merb_footnotes" do
4
+ it "should do nothing" do
5
+ true.should == true
6
+ end
7
+ end
@@ -0,0 +1 @@
1
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: merb_footnotes
3
+ version: !ruby/object:Gem::Version
4
+ version: "0.1"
5
+ platform: ruby
6
+ authors:
7
+ - Jacques Crocker
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-11-22 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: merb
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "1.0"
24
+ version:
25
+ description: Provides an extensible footnotes debugging bar to Merb development mode
26
+ email: merbjedi@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - README
33
+ - LICENSE
34
+ files:
35
+ - LICENSE
36
+ - README
37
+ - Rakefile
38
+ - lib/merb-plugins-footnotes.rb
39
+ - lib/merb_footnotes
40
+ - lib/merb_footnotes/filter.rb
41
+ - lib/merb_footnotes/formatter.rb
42
+ - lib/merb_footnotes/instrumentation.rb
43
+ - lib/merb_footnotes/notes
44
+ - lib/merb_footnotes/notes/abstract_note.rb
45
+ - lib/merb_footnotes/notes/controller_note.rb
46
+ - lib/merb_footnotes/notes/cookies_note.rb
47
+ - lib/merb_footnotes/notes/env_note.rb
48
+ - lib/merb_footnotes/notes/files_note.rb
49
+ - lib/merb_footnotes/notes/filters_note.rb
50
+ - lib/merb_footnotes/notes/javascripts_note.rb
51
+ - lib/merb_footnotes/notes/layout_note.rb
52
+ - lib/merb_footnotes/notes/log_note.rb
53
+ - lib/merb_footnotes/notes/params_note.rb
54
+ - lib/merb_footnotes/notes/partials_note.rb
55
+ - lib/merb_footnotes/notes/queries_note.rb
56
+ - lib/merb_footnotes/notes/routes_note.rb
57
+ - lib/merb_footnotes/notes/session_note.rb
58
+ - lib/merb_footnotes/notes/stylesheets_note.rb
59
+ - lib/merb_footnotes/notes/view_note.rb
60
+ - spec/merb_footnotes_spec.rb
61
+ - spec/spec_helper.rb
62
+ has_rdoc: true
63
+ homepage: http://merbjedi.com/
64
+ post_install_message:
65
+ rdoc_options: []
66
+
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: "0"
74
+ version:
75
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ version: "0"
80
+ version:
81
+ requirements: []
82
+
83
+ rubyforge_project: merb
84
+ rubygems_version: 1.3.1
85
+ signing_key:
86
+ specification_version: 2
87
+ summary: Provides an extensible footnotes debugging bar to Merb development mode
88
+ test_files: []
89
+