meta_reports 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.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/Guardfile +15 -0
  3. data/LICENSE +20 -0
  4. data/README.md +146 -0
  5. data/Rakefile +29 -0
  6. data/app/assets/images/meta_reports/print.png +0 -0
  7. data/app/assets/images/meta_reports/spreadsheet.png +0 -0
  8. data/app/assets/javascripts/meta_reports/reports.js +2 -0
  9. data/app/controllers/meta_reports/application_controller.rb +4 -0
  10. data/app/controllers/meta_reports/reports_controller.rb +91 -0
  11. data/app/helpers/meta_reports/reports_helper.rb +140 -0
  12. data/app/models/meta_reports/base.rb +90 -0
  13. data/app/models/meta_reports/data.rb +34 -0
  14. data/app/models/meta_reports/table.rb +80 -0
  15. data/config/routes.rb +9 -0
  16. data/db/migrate/20130801071213_create_meta_reports_reports.rb +17 -0
  17. data/lib/generators/meta_reports/install_generator.rb +40 -0
  18. data/lib/generators/meta_reports/templates/models/report.rb +30 -0
  19. data/lib/generators/meta_reports/templates/views/_form.html.erb +45 -0
  20. data/lib/generators/meta_reports/templates/views/edit.html.erb +6 -0
  21. data/lib/generators/meta_reports/templates/views/forms/_form_example.html.erb +1 -0
  22. data/lib/generators/meta_reports/templates/views/forms/form.html.erb +17 -0
  23. data/lib/generators/meta_reports/templates/views/index.html.erb +36 -0
  24. data/lib/generators/meta_reports/templates/views/new.html.erb +5 -0
  25. data/lib/generators/meta_reports/templates/views/templates/_default.html.erb +26 -0
  26. data/lib/generators/meta_reports/templates/views/templates/_default_footer.pdf.prawn +12 -0
  27. data/lib/generators/meta_reports/templates/views/templates/_default_header.pdf.prawn +14 -0
  28. data/lib/generators/meta_reports/templates/views/templates/_default_header.xlsx.axlsx +20 -0
  29. data/lib/generators/meta_reports/templates/views/templates/_default_table.html.erb +24 -0
  30. data/lib/generators/meta_reports/templates/views/templates/_default_table.pdf.prawn +29 -0
  31. data/lib/generators/meta_reports/templates/views/templates/default.html.erb +1 -0
  32. data/lib/generators/meta_reports/templates/views/templates/default.pdf.prawn +26 -0
  33. data/lib/generators/meta_reports/templates/views/templates/default.xlsx.axlsx +43 -0
  34. data/lib/meta_reports.rb +4 -0
  35. data/lib/meta_reports/engine.rb +15 -0
  36. data/lib/meta_reports/version.rb +3 -0
  37. data/lib/tasks/meta_reports_tasks.rake +4 -0
  38. data/spec/dummy/README.rdoc +261 -0
  39. data/spec/dummy/Rakefile +7 -0
  40. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  41. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  42. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  43. data/spec/dummy/app/controllers/home_controller.rb +4 -0
  44. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  45. data/spec/dummy/app/models/meta_reports/report.rb +30 -0
  46. data/spec/dummy/app/views/home/index.html.erb +4 -0
  47. data/spec/dummy/app/views/layouts/application.html.erb +16 -0
  48. data/spec/dummy/app/views/meta_reports/reports/_form.html.erb +45 -0
  49. data/spec/dummy/app/views/meta_reports/reports/edit.html.erb +6 -0
  50. data/spec/dummy/app/views/meta_reports/reports/forms/_form_moo.html.erb +1 -0
  51. data/spec/dummy/app/views/meta_reports/reports/forms/form.html.erb +17 -0
  52. data/spec/dummy/app/views/meta_reports/reports/index.html.erb +36 -0
  53. data/spec/dummy/app/views/meta_reports/reports/new.html.erb +5 -0
  54. data/spec/dummy/app/views/meta_reports/reports/templates/_default.html.erb +26 -0
  55. data/spec/dummy/app/views/meta_reports/reports/templates/_default_footer.pdf.prawn +12 -0
  56. data/spec/dummy/app/views/meta_reports/reports/templates/_default_header.pdf.prawn +14 -0
  57. data/spec/dummy/app/views/meta_reports/reports/templates/_default_header.xlsx.axlsx +20 -0
  58. data/spec/dummy/app/views/meta_reports/reports/templates/_default_table.html.erb +24 -0
  59. data/spec/dummy/app/views/meta_reports/reports/templates/_default_table.pdf.prawn +29 -0
  60. data/spec/dummy/app/views/meta_reports/reports/templates/default.html.erb +1 -0
  61. data/spec/dummy/app/views/meta_reports/reports/templates/default.pdf.prawn +26 -0
  62. data/spec/dummy/app/views/meta_reports/reports/templates/default.xlsx.axlsx +43 -0
  63. data/spec/dummy/config.ru +4 -0
  64. data/spec/dummy/config/application.rb +65 -0
  65. data/spec/dummy/config/boot.rb +10 -0
  66. data/spec/dummy/config/database.yml +25 -0
  67. data/spec/dummy/config/environment.rb +5 -0
  68. data/spec/dummy/config/environments/development.rb +37 -0
  69. data/spec/dummy/config/environments/production.rb +67 -0
  70. data/spec/dummy/config/environments/test.rb +37 -0
  71. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  72. data/spec/dummy/config/initializers/inflections.rb +15 -0
  73. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  74. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  75. data/spec/dummy/config/initializers/session_store.rb +8 -0
  76. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  77. data/spec/dummy/config/locales/en.yml +5 -0
  78. data/spec/dummy/config/routes.rb +4 -0
  79. data/spec/dummy/config/routes_empty.rb +3 -0
  80. data/spec/dummy/config/routes_original.rb +4 -0
  81. data/spec/dummy/db/development.sqlite3 +0 -0
  82. data/spec/dummy/db/schema.rb +31 -0
  83. data/spec/dummy/log/development.log +22317 -0
  84. data/spec/dummy/public/404.html +26 -0
  85. data/spec/dummy/public/422.html +26 -0
  86. data/spec/dummy/public/500.html +25 -0
  87. data/spec/dummy/public/favicon.ico +0 -0
  88. data/spec/dummy/script/rails +6 -0
  89. data/spec/dummy/tmp/cache/assets/C9B/140/sprockets%2F805babf865ce32228222420a522c7b36 +0 -0
  90. data/spec/dummy/tmp/cache/assets/CBD/2B0/sprockets%2F9e22e937dd267c81a146665f15471b8e +0 -0
  91. data/spec/dummy/tmp/cache/assets/CD0/810/sprockets%2Fe858c95fa595e319dac0065d49982967 +0 -0
  92. data/spec/dummy/tmp/cache/assets/CD0/AC0/sprockets%2F1d341d7a2fc1328567d4b23e0809b2e2 +0 -0
  93. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  94. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  95. data/spec/dummy/tmp/cache/assets/D3D/EB0/sprockets%2F2d47bd3108d9abbb12c0497e36d9674d +0 -0
  96. data/spec/dummy/tmp/cache/assets/D40/8F0/sprockets%2F290aea2004dfecfc76f42e48970f1484 +0 -0
  97. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  98. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  99. data/spec/dummy/tmp/cache/assets/D61/310/sprockets%2Fc168b1c9be3e38ac1c8403a3074b5b8c +0 -0
  100. data/spec/dummy/tmp/cache/assets/D74/AE0/sprockets%2F9ad0425db5cfa16a9426f7b1a7958d7d +0 -0
  101. data/spec/dummy/tmp/cache/assets/D98/270/sprockets%2F0b7ba158ff62bbbb378d6bea80680c63 +0 -0
  102. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  103. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  104. data/spec/dummy/tmp/cache/assets/E5A/EF0/sprockets%2Fb0d5af721ea37c98fd4bccd8e1e5c6ab +0 -0
  105. data/spec/dummy/tmp/pids/server.pid +1 -0
  106. data/spec/features/dummy_spec.rb +42 -0
  107. data/spec/generators/install_spec.rb +51 -0
  108. data/spec/models/data_spec.rb +45 -0
  109. data/spec/models/table_spec.rb +78 -0
  110. data/spec/spec_helper.rb +41 -0
  111. metadata +454 -0
@@ -0,0 +1,90 @@
1
+ class MetaReports::Base < ActiveRecord::Base
2
+ attr_accessible :description, :direct, :group, :name, :target, :title, :views, :formats_mask
3
+ validates_presence_of :name, :title, :group
4
+
5
+ self.table_name = "meta_reports_reports"
6
+
7
+ def self.test_report(params)
8
+ {title: 'Test Report', subtitle: 'this is a test report', tables: {'Table 1' => [['One','Two','Three'],[1,2,3]]}}
9
+ end
10
+
11
+ #
12
+ # Utility methods
13
+ #
14
+
15
+ FORMATS = %w[html pdf xlsx]
16
+
17
+ def self.color(klass, row = 0)
18
+ color = COLORS[klass.to_sym]
19
+ return nil unless color
20
+ if color.is_a? Array
21
+ # the trailing split first is to drop any !important directive
22
+ # color = color[row%color.length].to_s.split.first
23
+ # the trailing gsub is to drop any !important directive
24
+ color = color[row%color.length].to_s.gsub(/\s.*$/,'')
25
+ end
26
+ if color.gsub!(/^\$/, '') # we have a variable
27
+ color = COLORS[color.to_sym]
28
+ if color.is_a? Array
29
+ choice = color.gsub!(/Odd/,'') ? 1 : 0
30
+ color = color[choice]
31
+ end
32
+ end
33
+ color
34
+ end
35
+
36
+ def self.format_mask(format)
37
+ 1 << (FORMATS.index(format.to_s) || -1)
38
+ end
39
+
40
+ def self.formats_mask(*formats)
41
+ formats.inject(0) {|mask, format| mask | (1 << (FORMATS.index(format.to_s) || -1) )}
42
+ end
43
+
44
+ def displays_all_formats?(*formats)
45
+ has_all = true
46
+ ([*formats] & FORMATS).each do |format|
47
+ i = FORMATS.index(format.to_s)
48
+ has_any = false if formats_mask[i] != 1
49
+ end
50
+ has_all
51
+ end
52
+
53
+ def displays_any_format?(*formats)
54
+ has_any = false
55
+ ([*formats] & FORMATS).each do |format|
56
+ i = FORMATS.index(format.to_s)
57
+ has_any = true if formats_mask[i] == 1
58
+ end
59
+ has_any
60
+ end
61
+
62
+ def formats=(formats)
63
+ self.formats_mask = ([*formats] & FORMATS).inject(0) { |sum,r| sum += 1 << FORMATS.index(r) }
64
+ end
65
+
66
+ def formats
67
+ FORMATS.reject { |r| (formats_mask || 0)[FORMATS.index(r)].zero? }
68
+ end
69
+
70
+ def format?(format)
71
+ i = FORMATS.index(format.to_s)
72
+ i ? (formats_mask[i] == 1) : nil
73
+ end
74
+
75
+ def run(params)
76
+ report = ::MetaReports::Report.send(name, params)
77
+ report[:id] = "report_#{name}"
78
+ report[:report] = self
79
+ report
80
+ end
81
+
82
+ def view
83
+ connection.execute("UPDATE meta_reports_reports SET views = views + 1 WHERE id = #{id}")
84
+ end
85
+
86
+ COLORS = {
87
+ even: 'efefef',
88
+ odd: 'ffffff',
89
+ }
90
+ end
@@ -0,0 +1,34 @@
1
+ class MetaReports::Data
2
+ def initialize
3
+ @hash = {tables: {}}
4
+ yield self if block_given?
5
+ self
6
+ end
7
+
8
+ def method_missing(method, *args, &block)
9
+ method_string = method.to_s
10
+ if method_string =~ /^(.+)=$/
11
+ @hash[$1.to_sym] = args.first
12
+ elsif @hash[method.to_sym]
13
+ @hash[method.to_sym]
14
+ else
15
+ @hash.send(method, *args)
16
+ end
17
+ end
18
+
19
+ def [](key)
20
+ @hash[key]
21
+ end
22
+
23
+ def []=(key, value)
24
+ @hash[key] = value
25
+ end
26
+
27
+ def tables
28
+ @hash[:tables]
29
+ end
30
+
31
+ def to_h
32
+ @hash
33
+ end
34
+ end
@@ -0,0 +1,80 @@
1
+ class MetaReports::Table
2
+ def initialize
3
+ @data = []
4
+ @options = {row_classes: {}}
5
+ yield self if block_given?
6
+ end
7
+
8
+ def method_missing(method, *args, &block)
9
+ method_string = method.to_s
10
+ if method_string =~ /^(.+)=$/
11
+ @options[$1.to_sym] = args.first
12
+ elsif @options[method.to_sym]
13
+ @options[method.to_sym]
14
+ else
15
+ super
16
+ end
17
+ end
18
+
19
+ # options methods
20
+
21
+ def [](key)
22
+ @options[key]
23
+ end
24
+
25
+ def []=(key,val)
26
+ @options[key] = val
27
+ end
28
+
29
+ def options
30
+ @options
31
+ end
32
+
33
+ def row_classes
34
+ @options[:row_classes]
35
+ end
36
+
37
+ # data methods
38
+
39
+ def <<(val)
40
+ @data << val
41
+ end
42
+
43
+ def +(arr)
44
+ @data += arr
45
+ end
46
+
47
+ def first
48
+ @data.first
49
+ end
50
+
51
+ def last
52
+ @data.last
53
+ end
54
+
55
+ def length
56
+ @data.length
57
+ end
58
+
59
+ def pop
60
+ @data.pop
61
+ end
62
+
63
+ def push(val)
64
+ @data.push(val)
65
+ end
66
+
67
+ def shift
68
+ @data.shift
69
+ end
70
+
71
+ def to_a
72
+ @data
73
+ end
74
+
75
+ def unshift(val)
76
+ @data.unshift(val)
77
+ end
78
+
79
+ alias_method :data, :to_a
80
+ end
@@ -0,0 +1,9 @@
1
+ MetaReports::Engine.routes.draw do
2
+ root to: "reports#index"
3
+
4
+ get 'reports/file/:dir' => 'reports#file', as: 'file'
5
+ resources :reports
6
+ match ':id(.:format)' => 'reports#show', as: 'short_show'
7
+ get ':id/edit' => 'reports#edit', as: 'short_edit'
8
+ get ':id/form' => 'reports#form', as: 'short_form'
9
+ end
@@ -0,0 +1,17 @@
1
+ class CreateMetaReportsReports < ActiveRecord::Migration
2
+ def change
3
+ create_table :meta_reports_reports do |t|
4
+ t.string :name
5
+ t.text :description
6
+ t.string :title
7
+ t.string :group
8
+ t.boolean :direct
9
+ t.integer :views
10
+ t.string :target
11
+ t.integer :formats_mask
12
+
13
+ t.timestamps
14
+ end
15
+ add_index :meta_reports_reports, :name
16
+ end
17
+ end
@@ -0,0 +1,40 @@
1
+ require 'rails/generators'
2
+
3
+ module MetaReports
4
+ module Generators
5
+ class InstallGenerator < Rails::Generators::Base
6
+ source_root File.expand_path('../templates', __FILE__)
7
+
8
+ desc 'Copy meta_reports migration, models, controllers, and views.'
9
+
10
+ def create_migration_file
11
+ Dir.chdir(Rails.root) do
12
+ `rake meta_reports:install:migrations`
13
+ end
14
+ end
15
+
16
+ def install_model
17
+ copy_file "models/report.rb", "app/models/meta_reports/report.rb"
18
+ end
19
+
20
+ def install_views
21
+ directory "views", "app/views/meta_reports/reports"
22
+ end
23
+
24
+ def mount_engine
25
+ routes_file = "#{Rails.root}/config/routes.rb"
26
+ unless open(routes_file).grep(/MetaReports::Engine/)
27
+ insert_into_file(routes_file, :after => /routes.draw.do\n/) do
28
+ %Q{
29
+ # This line mounts MetaReports's routes at /reports by default.
30
+ # This means, any requests to the /reports URL of your application will go to MetaReports::ReportsController#index.
31
+ # If you would like to change where this extension is mounted, simply change '/reports' to something different.
32
+ mount MetaReports::Engine => '/reports'
33
+
34
+ }
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,30 @@
1
+ class MetaReports::Report < MetaReports::Base
2
+
3
+ #
4
+ # Shared colors. The key is the class name, value is RGB in hex format
5
+ #
6
+
7
+ COLORS = {
8
+ even: 'efefef',
9
+ odd: 'ffffff',
10
+ }
11
+
12
+
13
+ #
14
+ # Reports
15
+ #
16
+
17
+ def self.example_report(params)
18
+ {title: 'Example Report', subtitle: 'this is a test report', tables: {'Table 1' => [['One','Two','Three'],[1,2,3]]}}
19
+ MetaReports::Data.new do |d|
20
+ d.title = 'Example Report'
21
+ d.subtitle = 'Of the Testing Kind'
22
+ d.description = 'This is a test report.'
23
+ d.tables["Table 1"] = MetaReports::Table.new do |t|
24
+ t << ['One', 'Two', 'Three']
25
+ t << [1, 2, 3]
26
+ end
27
+ end
28
+ end
29
+
30
+ end
@@ -0,0 +1,45 @@
1
+ <%= form_for(@report) do |f| %>
2
+ <% if @report.errors.any? %>
3
+ <div id="error_explanation">
4
+ <h2><%= pluralize(@report.errors.count, "error") %> prohibited this report from being saved:</h2>
5
+
6
+ <ul>
7
+ <% @report.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :name %><br />
16
+ <%= f.text_field :name %>
17
+ </div>
18
+ <div class="field">
19
+ <%= f.label :description %><br />
20
+ <%= f.text_area :description %>
21
+ </div>
22
+ <div class="field">
23
+ <%= f.label :title %><br />
24
+ <%= f.text_field :title %>
25
+ </div>
26
+ <div class="field">
27
+ <%= f.label :group %><br />
28
+ <%= f.text_field :group %>
29
+ </div>
30
+ <div class="field">
31
+ <%= f.label :direct %><br />
32
+ <%= f.check_box :direct %>
33
+ </div>
34
+ <div class="field">
35
+ <%= f.label :views %><br />
36
+ <%= f.number_field :views, disabled: true %>
37
+ </div>
38
+ <div class="field">
39
+ <%= f.label :target %><br />
40
+ <%= f.text_field :target %>
41
+ </div>
42
+ <div class="actions">
43
+ <%= f.submit %>
44
+ </div>
45
+ <% end %>
@@ -0,0 +1,6 @@
1
+ <h1>Editing report</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Show', meta_reports.short_form_path(@report) %> |
6
+ <%= link_to 'Back', reports_path %>
@@ -0,0 +1 @@
1
+ <%= select_tag :type, options_for_select(['One','Two']), include_blank: true %>
@@ -0,0 +1,17 @@
1
+ <h3><%= @report.title %></h3>
2
+ <%= form_tag(meta_reports.short_show_path(@report), id: 'meta_reports_report_form') do %>
3
+ <p>
4
+ <%= render "meta_reports/reports/forms/form_#{@report.name}" %>
5
+ </p>
6
+ <p class='form-actions'>
7
+ <% if @report.format? :html %>
8
+ <%= submit_tag 'Display', data: {action: "/reports/#{@report.name}"} %>
9
+ <% end -%>
10
+ <% if @report.format? :pdf %>
11
+ <%= image_submit_tag image_path('meta_reports/print.png'), name: 'format_print', align: 'absmiddle', data: {action: "/reports/#{@report.name}.pdf", target: '_blank'} %>
12
+ <% end -%>
13
+ <% if @report.format? :xlsx %>
14
+ <%= image_submit_tag image_path('meta_reports/spreadsheet.png'), name: 'format_xlsx', align: 'absmiddle', data: {action: "/reports/#{@report.name}.xlsx", target: '_blank'} %>
15
+ <% end -%>
16
+ </p>
17
+ <% end %>
@@ -0,0 +1,36 @@
1
+ <h1>Listing reports</h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ <th>Description</th>
7
+ <th>Title</th>
8
+ <th>Group</th>
9
+ <th>Direct</th>
10
+ <th>Views</th>
11
+ <th>Target</th>
12
+ <th></th>
13
+ <th></th>
14
+ <th></th>
15
+ </tr>
16
+
17
+ <% @reports.each do |report| %>
18
+ <tr>
19
+ <td><%= report.name %></td>
20
+ <td><%= report.description %></td>
21
+ <td><%= report.title %></td>
22
+ <td><%= report.group %></td>
23
+ <td><%= report.direct %></td>
24
+ <td><%= report.views %></td>
25
+ <td><%= report.target %></td>
26
+ <td><%= report_link(report, 'Show') %></td>
27
+ <td><%= link_to 'Edit', edit_report_path(report) %></td>
28
+ <td><%= link_to 'Destroy', report, method: :delete, data: { confirm: 'Are you sure?' } %></td>
29
+ </tr>
30
+ <% end %>
31
+ </table>
32
+
33
+ <br />
34
+
35
+ <%= link_to 'New Report', new_report_path %>
36
+
@@ -0,0 +1,5 @@
1
+ <h1>New report</h1>
2
+
3
+ <%= render 'form' %>
4
+
5
+ <%= link_to 'Back', reports_path %>
@@ -0,0 +1,26 @@
1
+ <%
2
+ report = @report if defined?(report).nil?
3
+ %>
4
+ <%= content_tag(:div, :id => report[:id]) do %>
5
+ <%
6
+ title = report[:title]
7
+ title += '<br>'+content_tag(:span, report[:subtitle], :class => 'small') if report[:subtitle]
8
+ %>
9
+ <%= content_tag(:h3, title.html_safe) if title %>
10
+ <div>
11
+ <%= report_alt_links(report[:report], params) %>
12
+ <% if report[:description] %><br><p class='description'><%= report[:description] %></p><% end %>
13
+ </div>
14
+
15
+ <%= content_tag(:div, "No data found", :class => 'textcenter') if report[:tables].blank? %>
16
+
17
+ <%
18
+ table_names = report[:table_order] || report[:tables].keys.sort_by {|k| k.to_s}
19
+ table_names.each do |table_name| %>
20
+ <%= render partial: 'meta_reports/reports/templates/default_table', locals: {table_name: table_name, table: report[:tables][table_name]} %>
21
+ <% end %>
22
+ <% end %>
23
+
24
+ <% unless request.xhr? %>
25
+ <%= link_to 'Reports', '/meta_reports' %>
26
+ <% end -%>