rails-footnotes 3.6.3 → 3.6.4

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.
@@ -1,19 +1,19 @@
1
- require "#{File.dirname(__FILE__)}/abstract_note"
2
-
3
- module Footnotes
4
- module Notes
5
- class GeneralNote < AbstractNote
6
- def title
7
- 'General Debug'
8
- end
9
-
10
- def legend
11
- 'General (id="general_debug_info")'
12
- end
13
-
14
- def content
15
- 'You can use this tab to debug other parts of your application, for example Javascript.'
16
- end
17
- end
18
- end
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module Footnotes
4
+ module Notes
5
+ class GeneralNote < AbstractNote
6
+ def title
7
+ 'General Debug'
8
+ end
9
+
10
+ def legend
11
+ 'General (id="general_debug_info")'
12
+ end
13
+
14
+ def content
15
+ 'You can use this tab to debug other parts of your application, for example Javascript.'
16
+ end
17
+ end
18
+ end
19
19
  end
@@ -1,16 +1,16 @@
1
- require "#{File.dirname(__FILE__)}/files_note"
2
-
3
- module Footnotes
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
1
+ require "#{File.dirname(__FILE__)}/files_note"
2
+
3
+ module Footnotes
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
16
  end
@@ -1,28 +1,28 @@
1
- require "#{File.dirname(__FILE__)}/abstract_note"
2
-
3
- module Footnotes
4
- module Notes
5
- class LayoutNote < AbstractNote
6
- def initialize(controller)
7
- @controller = controller
8
- end
9
-
10
- def row
11
- :edit
12
- end
13
-
14
- def link
15
- escape(Footnotes::Filter.prefix(filename, 1, 1))
16
- end
17
-
18
- def valid?
19
- prefix? && @controller.active_layout
20
- end
21
-
22
- protected
23
- def filename
24
- File.join(File.expand_path(RAILS_ROOT), 'app', 'layouts', "#{@controller.active_layout.to_s.underscore}").sub('/layouts/layouts/', '/views/layouts/')
25
- end
26
- end
27
- end
28
- end
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module Footnotes
4
+ module Notes
5
+ class LayoutNote < AbstractNote
6
+ def initialize(controller)
7
+ @controller = controller
8
+ end
9
+
10
+ def row
11
+ :edit
12
+ end
13
+
14
+ def link
15
+ escape(Footnotes::Filter.prefix(filename, 1, 1))
16
+ end
17
+
18
+ def valid?
19
+ prefix? && @controller.active_layout
20
+ end
21
+
22
+ protected
23
+ def filename
24
+ File.join(File.expand_path(RAILS_ROOT), 'app', 'layouts', "#{@controller.active_layout.to_s.underscore}").sub('/layouts/layouts/', '/views/layouts/')
25
+ end
26
+ end
27
+ end
28
+ end
@@ -1,36 +1,47 @@
1
- require "#{File.dirname(__FILE__)}/abstract_note"
2
-
3
- module Footnotes
4
- module Notes
5
- class LogNote < AbstractNote
6
- def initialize(controller)
7
- @controller = controller
8
- end
9
-
10
- def content
11
- escape(log_tail).gsub("\n","<br />")
12
- end
13
-
14
- protected
15
- def log_tail
16
- filename = if RAILS_DEFAULT_LOGGER.instance_variable_get('@log')
17
- RAILS_DEFAULT_LOGGER.instance_variable_get('@log').path
18
- else
19
- RAILS_DEFAULT_LOGGER.instance_variable_get('@logdev').filename
20
- end
21
- file_string = File.open(filename).read.to_s
22
-
23
- # We try to select the specified action from the log
24
- # If we can't find it, we get the last 100 lines
25
- #
26
- if rindex = file_string.rindex('Processing '+@controller.controller_class_name+'#'+@controller.action_name)
27
- file_string[rindex..-1].gsub(/\e\[.+?m/, '')
28
- else
29
- lines = file_string.split("\n")
30
- index = [lines.size-100,0].max
31
- lines[index..-1].join("\n")
32
- end
33
- end
34
- end
35
- end
36
- end
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module Footnotes
4
+ module Notes
5
+ class LogNote < AbstractNote
6
+ @@log = []
7
+
8
+ def self.log(message)
9
+ @@log << message
10
+ end
11
+
12
+ def initialize(controller)
13
+ @controller = controller
14
+ end
15
+
16
+ def title
17
+ "Log (#{log.count("\n")})"
18
+ end
19
+
20
+ def content
21
+ escape(log.gsub(/\e\[.+?m/, '')).gsub("\n", '<br />')
22
+ end
23
+
24
+ def log
25
+ unless @log
26
+ @log = @@log.join('')
27
+ @@log = []
28
+ if rindex = @log.rindex('Processing '+@controller.controller_class_name+'#'+@controller.action_name)
29
+ @log = @log[rindex..-1]
30
+ end
31
+ end
32
+ @log
33
+ end
34
+
35
+ module LoggingExtensions
36
+ def add(*args, &block)
37
+ logged_message = super
38
+ Footnotes::Notes::LogNote.log(logged_message)
39
+ logged_message
40
+ end
41
+ end
42
+
43
+ Rails.logger.extend LoggingExtensions
44
+ end
45
+ end
46
+ end
47
+
@@ -1,19 +1,19 @@
1
- require "#{File.dirname(__FILE__)}/abstract_note"
2
-
3
- module Footnotes
4
- module Notes
5
- class ParamsNote < AbstractNote
6
- def initialize(controller)
7
- @params = controller.params.symbolize_keys
8
- end
9
-
10
- def title
11
- "Params (#{@params.length})"
12
- end
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module Footnotes
4
+ module Notes
5
+ class ParamsNote < AbstractNote
6
+ def initialize(controller)
7
+ @params = controller.params.symbolize_keys
8
+ end
9
+
10
+ def title
11
+ "Params (#{@params.length})"
12
+ end
13
13
 
14
14
  def content
15
- mount_table_for_hash(@params)
16
- end
17
- end
18
- end
15
+ mount_table_for_hash(@params)
16
+ end
17
+ end
18
+ end
19
19
  end
@@ -1,61 +1,61 @@
1
- require "#{File.dirname(__FILE__)}/abstract_note"
2
-
3
- module Footnotes
4
- module Notes
5
- class QueriesNote < AbstractNote
6
- @@alert_db_time = 0.16
7
- @@alert_sql_number = 8
8
- @@sql = []
9
- cattr_accessor :sql, :alert_db_time, :alert_sql_number, :alert_explain, :instance_writter => false
10
-
11
- def self.start!(controller)
12
- @@sql = []
13
- end
14
-
15
- def self.to_sym
16
- :queries
17
- end
18
-
19
- def title
20
- db_time = @@sql.inject(0){|sum, item| sum += item.time }
21
- query_color = generate_red_color(@@sql.length, alert_sql_number)
1
+ require "#{File.dirname(__FILE__)}/abstract_note"
2
+
3
+ module Footnotes
4
+ module Notes
5
+ class QueriesNote < AbstractNote
6
+ @@alert_db_time = 0.16
7
+ @@alert_sql_number = 8
8
+ @@sql = []
9
+ cattr_accessor :sql, :alert_db_time, :alert_sql_number, :alert_explain, :instance_writter => false
10
+
11
+ def self.start!(controller)
12
+ @@sql = []
13
+ end
14
+
15
+ def self.to_sym
16
+ :queries
17
+ end
18
+
19
+ def title
20
+ db_time = @@sql.inject(0){|sum, item| sum += item.time }
21
+ query_color = generate_red_color(@@sql.length, alert_sql_number)
22
22
  db_color = generate_red_color(db_time, alert_db_time)
23
-
24
- <<-TITLE
25
- <span style="background-color:#{query_color}">Queries (#{@@sql.length})</span>
26
- <span style="background-color:#{db_color}">DB (#{"%.6f" % db_time}s)</span>
27
- TITLE
28
- end
29
-
30
- def stylesheet
31
- <<-STYLESHEET
32
- #queries_debug_info table td, #queries_debug_info table th{border:1px solid #A00; padding:0 3px; text-align:center;}
33
- #queries_debug_info table thead, #queries_debug_info table tbody {color:#A00;}
34
- #queries_debug_info p {background-color:#F3F3FF; border:1px solid #CCC; margin:12px; padding:4px 6px;}
35
- #queries_debug_info a:hover {text-decoration:underline;}
36
- STYLESHEET
37
- end
38
-
39
- def content
40
- html = ''
41
-
42
- @@sql.each_with_index do |item, i|
43
- sql_links = []
44
- sql_links << "<a href=\"javascript:Footnotes.toggle('qtable_#{i}')\" style=\"color:#A00;\">explain</a>" if item.explain
45
- sql_links << "<a href=\"javascript:Footnotes.toggle('qtrace_#{i}')\" style=\"color:#00A;\">trace</a>" if item.trace
46
-
47
- html << <<-HTML
48
- <b id="qtitle_#{i}">#{escape(item.type.to_s.upcase)}</b> (#{sql_links.join(' | ')})<br />
49
- #{print_name_and_time(item.name, item.time)}<br />
50
- <span id="explain_#{i}">#{print_query(item.query)}</span><br />
51
- #{print_explain(i, item.explain) if item.explain}
52
- <p id="qtrace_#{i}" style="display:none;">#{parse_trace(item.trace) if item.trace}</p><br />
53
- HTML
54
- end
55
-
56
- return html
57
- end
58
-
23
+
24
+ <<-TITLE
25
+ <span style="background-color:#{query_color}">Queries (#{@@sql.length})</span>
26
+ <span style="background-color:#{db_color}">DB (#{"%.6f" % db_time}s)</span>
27
+ TITLE
28
+ end
29
+
30
+ def stylesheet
31
+ <<-STYLESHEET
32
+ #queries_debug_info table td, #queries_debug_info table th{border:1px solid #A00; padding:0 3px; text-align:center;}
33
+ #queries_debug_info table thead, #queries_debug_info table tbody {color:#A00;}
34
+ #queries_debug_info p {background-color:#F3F3FF; border:1px solid #CCC; margin:12px; padding:4px 6px;}
35
+ #queries_debug_info a:hover {text-decoration:underline;}
36
+ STYLESHEET
37
+ end
38
+
39
+ def content
40
+ html = ''
41
+
42
+ @@sql.each_with_index do |item, i|
43
+ sql_links = []
44
+ sql_links << "<a href=\"javascript:Footnotes.toggle('qtable_#{i}')\" style=\"color:#A00;\">explain</a>" if item.explain
45
+ sql_links << "<a href=\"javascript:Footnotes.toggle('qtrace_#{i}')\" style=\"color:#00A;\">trace</a>" if item.trace
46
+
47
+ html << <<-HTML
48
+ <b id="qtitle_#{i}">#{escape(item.type.to_s.upcase)}</b> (#{sql_links.join(' | ')})<br />
49
+ #{print_name_and_time(item.name, item.time)}<br />
50
+ <span id="explain_#{i}">#{print_query(item.query)}</span><br />
51
+ #{print_explain(i, item.explain) if item.explain}
52
+ <p id="qtrace_#{i}" style="display:none;">#{parse_trace(item.trace) if item.trace}</p><br />
53
+ HTML
54
+ end
55
+
56
+ return html
57
+ end
58
+
59
59
  protected
60
60
  def parse_explain(results)
61
61
  table = []
@@ -65,108 +65,108 @@ module Footnotes
65
65
  end
66
66
  table
67
67
  end
68
-
69
- def parse_trace(trace)
70
- trace.map do |t|
71
- s = t.split(':')
72
- %[<a href="#{escape(Footnotes::Filter.prefix("#{RAILS_ROOT}/#{s[0]}", s[1].to_i, 1))}">#{escape(t)}</a><br />]
73
- end.join
74
- end
75
-
76
- def print_name_and_time(name, time)
77
- "<span style='background-color:#{generate_red_color(time, alert_ratio)}'>#{escape(name || 'SQL')} (#{sprintf('%f', time)}s)</span>"
78
- end
79
-
80
- def print_query(query)
81
- escape(query.to_s.gsub(/(\s)+/, ' ').gsub('`', ''))
82
- end
83
-
68
+
69
+ def parse_trace(trace)
70
+ trace.map do |t|
71
+ s = t.split(':')
72
+ %[<a href="#{escape(Footnotes::Filter.prefix("#{RAILS_ROOT}/#{s[0]}", s[1].to_i, 1))}">#{escape(t)}</a><br />]
73
+ end.join
74
+ end
75
+
76
+ def print_name_and_time(name, time)
77
+ "<span style='background-color:#{generate_red_color(time, alert_ratio)}'>#{escape(name || 'SQL')} (#{sprintf('%f', time)}s)</span>"
78
+ end
79
+
80
+ def print_query(query)
81
+ escape(query.to_s.gsub(/(\s)+/, ' ').gsub('`', ''))
82
+ end
83
+
84
84
  def print_explain(i, explain)
85
85
  mount_table(parse_explain(explain), :id => "qtable_#{i}", :style => 'margin:10px;display:none;')
86
- end
87
-
86
+ end
87
+
88
88
  def generate_red_color(value, alert)
89
89
  c = ((value.to_f/alert).to_i - 1) * 16
90
90
  c = 0 if c < 0
91
91
  c = 15 if c > 15
92
-
93
- c = (15-c).to_s(16)
94
- "#ff#{c*4}"
92
+
93
+ c = (15-c).to_s(16)
94
+ "#ff#{c*4}"
95
95
  end
96
96
 
97
97
  def alert_ratio
98
98
  alert_db_time / alert_sql_number
99
- end
100
-
101
- end
102
- end
103
-
104
- module Extensions
105
- class Sql
106
- attr_accessor :type, :name, :time, :query, :explain, :trace
107
-
108
- def initialize(type, name, time, query, explain)
109
- @type = type
110
- @name = name
111
- @time = time
112
- @query = query
113
- @explain = explain
114
-
115
- # Strip, select those ones from app and reject first two, because they
116
- # are from the plugin
117
- @trace = Kernel.caller.collect(&:strip).select{|i| i.gsub!(/^#{RAILS_ROOT}\//im, '') }[2..-1]
118
- end
119
- end
120
-
121
- module QueryAnalyzer
122
- def self.included(base)
123
- base.class_eval do
124
- alias_method_chain :execute, :analyzer
125
- end
126
- end
127
-
128
- def execute_with_analyzer(query, name = nil)
129
- query_results = nil
130
- time = Benchmark.realtime { query_results = execute_without_analyzer(query, name) }
131
-
132
- if query =~ /^(select|create|update|delete)\b/i
133
- type = $&.downcase.to_sym
134
- explain = nil
135
-
136
- if adapter_name == 'MySQL' && type == :select
137
- log_silence do
138
- explain = execute_without_analyzer("EXPLAIN #{query}", name)
139
- end
140
- end
141
- Footnotes::Notes::QueriesNote.sql << Footnotes::Extensions::Sql.new(type, name, time, query, explain)
142
- end
143
-
144
- query_results
145
- end
146
- end
147
-
148
- module AbstractAdapter
149
- def log_silence
150
- result = nil
151
- if @logger
152
- @logger.silence do
153
- result = yield
154
- end
155
- else
156
- result = yield
157
- end
158
- result
159
- end
160
- end
161
-
162
- end
163
- end
164
-
165
- if Footnotes::Notes::QueriesNote.included?
166
- ActiveRecord::ConnectionAdapters::AbstractAdapter.send :include, Footnotes::Extensions::AbstractAdapter
167
- ActiveRecord::ConnectionAdapters.local_constants.each do |adapter|
168
- next unless adapter =~ /.*[^Abstract]Adapter$/
169
- next if adapter =~ /SQLiteAdapter$/
170
- eval("ActiveRecord::ConnectionAdapters::#{adapter}").send :include, Footnotes::Extensions::QueryAnalyzer
171
- end
172
- end
99
+ end
100
+
101
+ end
102
+ end
103
+
104
+ module Extensions
105
+ class Sql
106
+ attr_accessor :type, :name, :time, :query, :explain, :trace
107
+
108
+ def initialize(type, name, time, query, explain)
109
+ @type = type
110
+ @name = name
111
+ @time = time
112
+ @query = query
113
+ @explain = explain
114
+
115
+ # Strip, select those ones from app and reject first two, because they
116
+ # are from the plugin
117
+ @trace = Kernel.caller.collect(&:strip).select{|i| i.gsub!(/^#{RAILS_ROOT}\//im, '') }[2..-1]
118
+ end
119
+ end
120
+
121
+ module QueryAnalyzer
122
+ def self.included(base)
123
+ base.class_eval do
124
+ alias_method_chain :execute, :analyzer if respond_to?(:execute)
125
+ end
126
+ end
127
+
128
+ def execute_with_analyzer(query, name = nil)
129
+ query_results = nil
130
+ time = Benchmark.realtime { query_results = execute_without_analyzer(query, name) }
131
+
132
+ if query =~ /^(select|create|update|delete)\b/i
133
+ type = $&.downcase.to_sym
134
+ explain = nil
135
+
136
+ if adapter_name == 'MySQL' && type == :select
137
+ log_silence do
138
+ explain = execute_without_analyzer("EXPLAIN #{query}", name)
139
+ end
140
+ end
141
+ Footnotes::Notes::QueriesNote.sql << Footnotes::Extensions::Sql.new(type, name, time, query, explain)
142
+ end
143
+
144
+ query_results
145
+ end
146
+ end
147
+
148
+ module AbstractAdapter
149
+ def log_silence
150
+ result = nil
151
+ if @logger
152
+ @logger.silence do
153
+ result = yield
154
+ end
155
+ else
156
+ result = yield
157
+ end
158
+ result
159
+ end
160
+ end
161
+
162
+ end
163
+ end
164
+
165
+ if Footnotes::Notes::QueriesNote.included?
166
+ ActiveRecord::ConnectionAdapters::AbstractAdapter.send :include, Footnotes::Extensions::AbstractAdapter
167
+ ActiveRecord::ConnectionAdapters.local_constants.each do |adapter|
168
+ next unless adapter =~ /.*[^Abstract]Adapter$/
169
+ next if adapter =~ /SQLiteAdapter$/
170
+ eval("ActiveRecord::ConnectionAdapters::#{adapter}").send :include, Footnotes::Extensions::QueryAnalyzer
171
+ end
172
+ end