workbook_rails 0.1.0

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 (83) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +5 -0
  3. data/Gemfile +21 -0
  4. data/Gemfile.lock +207 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.md +216 -0
  7. data/Rakefile +29 -0
  8. data/lib/tasks/workbook_rails_tasks.rake +4 -0
  9. data/lib/workbook_rails.rb +5 -0
  10. data/lib/workbook_rails/action_controller.rb +51 -0
  11. data/lib/workbook_rails/engine.rb +25 -0
  12. data/lib/workbook_rails/template_handler.rb +23 -0
  13. data/lib/workbook_rails/version.rb +3 -0
  14. data/spec/ci.rb +3 -0
  15. data/spec/dummy/Rakefile +6 -0
  16. data/spec/dummy/app/assets/javascripts/application.js +13 -0
  17. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  18. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  19. data/spec/dummy/app/controllers/home_controller.rb +60 -0
  20. data/spec/dummy/app/controllers/likes_controller.rb +18 -0
  21. data/spec/dummy/app/controllers/users_controller.rb +16 -0
  22. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  23. data/spec/dummy/app/mailers/notifier.rb +14 -0
  24. data/spec/dummy/app/models/like.rb +3 -0
  25. data/spec/dummy/app/models/user.rb +8 -0
  26. data/spec/dummy/app/views/home/_cover_sheet.xlsx.wb +2 -0
  27. data/spec/dummy/app/views/home/generic.wb +5 -0
  28. data/spec/dummy/app/views/home/index.html.erb +4 -0
  29. data/spec/dummy/app/views/home/index.xls.wb +5 -0
  30. data/spec/dummy/app/views/home/index.xlsx.wb +5 -0
  31. data/spec/dummy/app/views/home/only_html.html.erb +1 -0
  32. data/spec/dummy/app/views/home/useheader.xlsx.wb +5 -0
  33. data/spec/dummy/app/views/home/withpartial.xlsx.wb +6 -0
  34. data/spec/dummy/app/views/layouts/application.html.erb +12 -0
  35. data/spec/dummy/app/views/likes/index.html.erb +17 -0
  36. data/spec/dummy/app/views/likes/index.xlsx.wb +5 -0
  37. data/spec/dummy/app/views/notifier/instructions.html.erb +14 -0
  38. data/spec/dummy/app/views/notifier/instructions.txt.erb +6 -0
  39. data/spec/dummy/app/views/users/index.html.erb +23 -0
  40. data/spec/dummy/app/views/users/mailers/instructions.xlsx.wb +3 -0
  41. data/spec/dummy/app/views/users/respond_with.xlsx.wb +5 -0
  42. data/spec/dummy/bin/bundle +3 -0
  43. data/spec/dummy/bin/rails +4 -0
  44. data/spec/dummy/bin/rake +4 -0
  45. data/spec/dummy/config.ru +4 -0
  46. data/spec/dummy/config/application.rb +34 -0
  47. data/spec/dummy/config/boot.rb +5 -0
  48. data/spec/dummy/config/database.yml +25 -0
  49. data/spec/dummy/config/environment.rb +5 -0
  50. data/spec/dummy/config/environments/development.rb +37 -0
  51. data/spec/dummy/config/environments/production.rb +83 -0
  52. data/spec/dummy/config/environments/test.rb +44 -0
  53. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  54. data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
  55. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  56. data/spec/dummy/config/initializers/inflections.rb +16 -0
  57. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  58. data/spec/dummy/config/initializers/secret_token.rb +2 -0
  59. data/spec/dummy/config/initializers/session_store.rb +3 -0
  60. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  61. data/spec/dummy/config/locales/en.yml +23 -0
  62. data/spec/dummy/config/routes.rb +17 -0
  63. data/spec/dummy/config/secrets.yml +22 -0
  64. data/spec/dummy/db/migrate/20120717192452_create_users.rb +12 -0
  65. data/spec/dummy/db/migrate/20121206210955_create_likes.rb +10 -0
  66. data/spec/dummy/db/schema.rb +32 -0
  67. data/spec/dummy/db/test.sqlite3 +0 -0
  68. data/spec/dummy/log/test.log +8575 -0
  69. data/spec/dummy/public/404.html +67 -0
  70. data/spec/dummy/public/422.html +67 -0
  71. data/spec/dummy/public/500.html +66 -0
  72. data/spec/dummy/public/favicon.ico +0 -0
  73. data/spec/spec_helper.rb +29 -0
  74. data/spec/template_handler_spec.rb +35 -0
  75. data/spec/test_3.2.sh +4 -0
  76. data/spec/test_4.0.sh +4 -0
  77. data/spec/test_4.1.sh +4 -0
  78. data/spec/test_4.2.sh +4 -0
  79. data/spec/test_all_rails.sh +4 -0
  80. data/spec/workbook_mailer_spec.rb +16 -0
  81. data/spec/workbook_renderer_spec.rb +21 -0
  82. data/spec/workbook_request_spec.rb +168 -0
  83. metadata +365 -0
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'WorkbookRails'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ require "rspec/core/rake_task"
24
+ RSpec::Core::RakeTask.new('spec')
25
+
26
+ task :default => :spec
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :workbook_rails do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,5 @@
1
+ require 'workbook_rails/engine'
2
+ module WorkbookRails
3
+ FORMATS = [:xlsx, :xls]
4
+ end
5
+
@@ -0,0 +1,51 @@
1
+ #
2
+ # You can always specify a template:
3
+ #
4
+ # def called_action
5
+ # render xlsx: 'filename', template: 'controller/diff_action'
6
+ # end
7
+ #
8
+ # And the normal use case works:
9
+ #
10
+ # def called_action
11
+ # render 'diff_action'
12
+ # # or
13
+ # render 'controller/diff_action'
14
+ # end
15
+ #
16
+ WorkbookRails::FORMATS.each do |format|
17
+ ActionController::Renderers.add format do |filename, options|
18
+ if options[:template] == action_name
19
+ options[:template] = filename.gsub(/^.*\//,'')
20
+ end
21
+
22
+ # disposition / filename
23
+ disposition = options.delete(:disposition) || 'attachment'
24
+ if file_name = options.delete(:filename)
25
+ file_name += ".#{format}" unless file_name =~ /\.#{format}$/
26
+ else
27
+ file_name = "#{filename.gsub(/^.*\//,'')}.#{format}"
28
+ end
29
+
30
+ options = options.merge(:formats => [format])
31
+ send_data render_to_string(options), :filename => file_name, :type => Mime::Type.lookup_by_extension(format), :disposition => disposition
32
+ end
33
+ end
34
+
35
+ # For respond_to default
36
+ begin
37
+ ActionController::Responder
38
+ rescue
39
+ else
40
+ class ActionController::Responder
41
+ WorkbookRails::FORMATS.each do |format|
42
+ define_method "to_#{format}" do
43
+ if @default_response
44
+ @default_response.call(options)
45
+ else
46
+ controller.render options.reverse_merge(format => controller.action_name)
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,25 @@
1
+ require 'workbook'
2
+ require 'workbook_rails/template_handler'
3
+
4
+ module WorkbookRails
5
+ class Engine < Rails::Engine
6
+ initializer 'workbook_rails.action_view' do
7
+ ActiveSupport.on_load :action_view do
8
+ ::ActionView::Template.register_template_handler :wb, WorkbookRails::TemplateHandler
9
+ end
10
+ end
11
+
12
+ initializer 'workbook_rails.action_controller' do
13
+ ActiveSupport.on_load :action_controller do
14
+ require 'workbook_rails/action_controller'
15
+ end
16
+ end
17
+
18
+ unless Mime::Type.lookup_by_extension(:xlsx)
19
+ Mime::Type.register "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", :xlsx
20
+ end
21
+ unless Mime::Type.lookup_by_extension(:xls)
22
+ Mime::Type.register "application/vnd.ms-excel", :xls
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,23 @@
1
+ module WorkbookRails
2
+ class TemplateHandler
3
+ class_attribute :default_format
4
+ self.default_format = :xlsx
5
+
6
+ def self.workbook_to_string(workbook, format)
7
+ case format
8
+ when :xlsx then workbook.stream_xlsx
9
+ when :xls then
10
+ io = StringIO.new
11
+ workbook.to_xls.write(io)
12
+ io.string
13
+ end
14
+ end
15
+
16
+ def self.call(template)
17
+ "workbook = Workbook::Book.new;\n" +
18
+ template.source +
19
+ ";\nWorkbookRails::TemplateHandler.workbook_to_string(workbook, lookup_context.rendered_format);"
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,3 @@
1
+ module WorkbookRails
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ exit system('cd spec/dummy && bundle install --without debug && bundle exec rake db:create && bundle exec rake db:migrate && cd ../../ && bundle exec rspec spec')
@@ -0,0 +1,6 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+
6
+ Rails.application.load_tasks
@@ -0,0 +1,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -0,0 +1,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -0,0 +1,5 @@
1
+ class ApplicationController < ActionController::Base
2
+ # Prevent CSRF attacks by raising an exception.
3
+ # For APIs, you may want to use :null_session instead.
4
+ protect_from_forgery with: :exception
5
+ end
@@ -0,0 +1,60 @@
1
+ #---
2
+ # Excerpted from "Crafting Rails Applications",
3
+ # published by The Pragmatic Bookshelf.
4
+ # Copyrights apply to this code. It may not be used to create training material,
5
+ # courses, books, articles, and the like. Contact us if you are in doubt.
6
+ # We make no guarantees that this code is fit for any purpose.
7
+ # Visit http://www.pragmaticprogrammer.com/titles/jvrails for more book information.
8
+ #---
9
+ class HomeController < ApplicationController
10
+ def index
11
+ end
12
+
13
+ def generic
14
+ respond_to do |format|
15
+ format.html
16
+ format.xlsx
17
+ format.xls
18
+ end
19
+ end
20
+
21
+ def only_html; end
22
+
23
+ def another
24
+ render :xlsx => "index", :filename => "filename_test.xlsx"
25
+ end
26
+
27
+ def render_elsewhere
28
+ case params[:type]
29
+ when '1'
30
+ render :xlsx => "home/index", :template => 'users/respond_with'
31
+ when '2'
32
+ render :xlsx => "users/respond_with", :template => 'users/respond_with'
33
+ when '3'
34
+ render template: "users/respond_with"
35
+ when '4'
36
+ render "users/respond_with"
37
+ else
38
+ render :xlsx => "index"
39
+ end
40
+ end
41
+
42
+ def render_file_path
43
+ render :xlsx => 'index', :file => Rails.root.join('app','views','users','respond_with')
44
+ end
45
+
46
+ def withpartial
47
+ end
48
+
49
+ def useheader
50
+ respond_to do |format|
51
+ format.xlsx {
52
+ if params[:set_direct]
53
+ response.headers['Content-Disposition'] = "attachment; filename=\"filename_test.xlsx\""
54
+ else
55
+ render xlsx: "useheader", filename: "filename_test.xlsx"
56
+ end
57
+ }
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,18 @@
1
+ class LikesController < ApplicationController
2
+ # GET /likes
3
+ # GET /likes.json
4
+ def index
5
+ @user = User.find(params[:user_id])
6
+ @likes = @user.likes
7
+
8
+ respond_to do |format|
9
+ format.html # index.html.erb
10
+ format.xlsx
11
+ end
12
+ end
13
+
14
+ def render_elsewhere
15
+ @user = User.find(params[:user_id])
16
+ render :xlsx => "index", :template => 'users/respond_with'
17
+ end
18
+ end
@@ -0,0 +1,16 @@
1
+ class UsersController < ApplicationController
2
+ respond_to :xlsx, :html
3
+
4
+ def show
5
+ @user = User.find(params[:id])
6
+ respond_with(@user) do |format|
7
+ format.xlsx { render "respond_with" }
8
+ end
9
+ end
10
+
11
+ def send_instructions
12
+ @user = User.find(params[:user_id])
13
+ @user.send_instructions
14
+ render text: "Email sent"
15
+ end
16
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,14 @@
1
+ class Notifier < ActionMailer::Base
2
+ default :from => 'noreply@company.com'
3
+
4
+ def instructions(user)
5
+ @user = user
6
+
7
+ # normal syntax
8
+ xlsx = render_to_string handlers: [:wb], template: 'users/mailers/instructions', layout: false, formats: [:xlsx]
9
+ attachments["user_#{user.id}.xlsx"] = {mime_type: Mime::XLSX, content: xlsx}
10
+
11
+ mail :to => user.email, :subject => 'Instructions'
12
+ end
13
+
14
+ end
@@ -0,0 +1,3 @@
1
+ class Like < ActiveRecord::Base
2
+ belongs_to :user
3
+ end
@@ -0,0 +1,8 @@
1
+ class User < ActiveRecord::Base
2
+ has_many :likes
3
+
4
+ def send_instructions
5
+ mail = Notifier.instructions(self)
6
+ mail.send(mail.respond_to?(:deliver_now) ? :deliver_now : :deliver)
7
+ end
8
+ end
@@ -0,0 +1,2 @@
1
+ wb.sheet.name = "Cover Sheet"
2
+ wb.sheet.table << ['Cover', 'Sheet']
@@ -0,0 +1,5 @@
1
+ workbook.sheet.name = "Foobar"
2
+ workbook.sheet.table.push ['Bad', 'spellers', 'of', 'the', 'world', '...']
3
+ workbook.sheet.table.push ['Untie!']
4
+ workbook.sheet.table['A2'].rowspan = 2
5
+ workbook.sheet.table['A2'].format = {width: 16, font_weight: 'bold'}
@@ -0,0 +1,4 @@
1
+ <p>Hey, you can download the xlsx for this page by clicking the link below:</p>
2
+ <p><%= link_to "XLSX", home_path("xlsx") %></p>
3
+ <p><%= link_to "Another", '/another.xlsx' %></p>
4
+ <p><%= link_to "User header", '/useheader.xlsx' %></p>
@@ -0,0 +1,5 @@
1
+ workbook.sheet.name = "Foobar"
2
+ workbook.sheet.table.push ['Bad', 'spellers', 'of', 'the', 'world', '...']
3
+ workbook.sheet.table.push ['Untie!']
4
+ workbook.sheet.table['A2'].rowspan = 2
5
+ workbook.sheet.table['A2'].format = {width: 16, font_weight: 'bold'}
@@ -0,0 +1,5 @@
1
+ workbook.sheet.name = "Foobar"
2
+ workbook.sheet.table.push ['Bad', 'spellers', 'of', 'the', 'world', '...']
3
+ workbook.sheet.table.push ['Untie!']
4
+ workbook.sheet.table['A2'].rowspan = 2
5
+ workbook.sheet.table['A2'].format = {width: 16, font_weight: 'bold'}
@@ -0,0 +1 @@
1
+ <p>Foo, bar</p>
@@ -0,0 +1,5 @@
1
+ workbook.sheet.name = "Useheader"
2
+ workbook.sheet.table.push ['Bad', 'spellers', 'of', 'the', 'world', '...']
3
+ workbook.sheet.table.push ['Untie!']
4
+ workbook.sheet.table['A2'].rowspan = 2
5
+ workbook.sheet.table['A2'].format = {width: 16, font_weight: 'bold'}
@@ -0,0 +1,6 @@
1
+ render :partial => 'cover_sheet', :locals => {:wb => workbook}
2
+ workbook << [['Bad', 'spellers', 'of', 'the', 'world', '...'], ['Untie!']]
3
+ sheet = workbook.last
4
+ sheet.name = 'Foobar'
5
+ sheet.table['A2'].rowspan = 2
6
+ sheet.table['A2'].format = {width: 16, font_weight: 'bold'}
@@ -0,0 +1,12 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Dummy 4</title>
5
+ <%= csrf_meta_tags %>
6
+ </head>
7
+ <body>
8
+
9
+ <%= yield %>
10
+
11
+ </body>
12
+ </html>
@@ -0,0 +1,17 @@
1
+ <h1>Listing likes for <%= @user.name %></h1>
2
+
3
+ <table>
4
+ <tr>
5
+ <th>Name</th>
6
+ </tr>
7
+
8
+ <% @likes.each do |like| %>
9
+ <tr>
10
+ <td><%= like.name %></td>
11
+ </tr>
12
+ <% end %>
13
+ </table>
14
+
15
+ <br />
16
+
17
+ <%= link_to 'New Like', new_like_path %>
@@ -0,0 +1,5 @@
1
+ workbook.sheet.name = "Foobar"
2
+ workbook.sheet.table.push [@user.name]
3
+ @likes.each do |like|
4
+ workbook.sheet.table << [like.name]
5
+ end
@@ -0,0 +1,14 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta content='text/html; charset=UTF-8' http-equiv='Content-Type' />
5
+ </head>
6
+ <body>
7
+ <h1>Instructions</h1>
8
+ <p>
9
+ You have successfully signed up to example.com,
10
+ your username is: <%= @user.email %>.<br/>
11
+ </p>
12
+ <p>Thanks for joining and have a great day!</p>
13
+ </body>
14
+ </html>
@@ -0,0 +1,6 @@
1
+ Instructions
2
+
3
+ You have successfully signed up to example.com,
4
+ your username is: <%= @user.email %>.
5
+
6
+ Thanks for joining and have a great day!