csv_streamer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,41 @@
1
+ * Added dependencies and simplified contributor setup
2
+
3
+ == 2.0.1 release 2011-04-22
4
+ * Remove cruft from test app
5
+ * Exclude spec from release
6
+
7
+ == 2.0.0 release 2011-04-22
8
+ * Move to Jeweler for release management
9
+ * Official Rails 3 release without regard for Rails 2
10
+ * Fix specs for Rspec 2.5 and Rails 3.0.7
11
+
12
+ == 1.1.8 (not released to gemcutter)
13
+ * Specs (Vidmantas Kabosis)
14
+ * Ruby 1.9 compability (Vidmantas Kabosis)
15
+ * CSV options are again passed to the builder (Vidmantas Kabosis)
16
+
17
+ == 1.1.7 release 2009-12-27
18
+
19
+ * Forgot to add transliterating filter to gem spec
20
+
21
+ == 1.1.6 release 2009-12-18
22
+
23
+ * Generate csv before setting headers so that errors are displayed in-browser instead of downloaded (Gabe da Silveira)
24
+ * Tweak README for gemcutter download. (Gabe da Silveira)
25
+
26
+ == 1.1.5 release 2009-12-18
27
+
28
+ * Do transliteration before exporting to CSV, not after (Tom Stuart)
29
+ * Released on gemcutter (Gabe da Silveira)
30
+
31
+ == 1.1.4 release 2009-07-27
32
+
33
+ * Merged some patches:
34
+ * Added gem spec (Jan De Poorter)
35
+ * Set the correct response headers to work with IE, made the existing ones a little more robust (Jose Fernandez)
36
+ * Created changelog, updated docs (Michael Reinsch)
37
+
38
+ == 1.0 released 2008
39
+
40
+ * The original csv_builder plugin, released by Econsultancy.com
41
+
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Econsultancy.com
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,105 @@
1
+ #Fawce's notes on forking:
2
+ I'm forking the project to add support for streaming responses. Many of the csv files I'm generating are quite large, and need to be streamed rather than return in a single shot. I'm basing my stream handling on [an example from David's Computer Stuff Journal](http://journal.dedasys.com/2006/06/08/streaming-programmatically-generated-content-from-rails)
3
+
4
+ ========
5
+ **Important Note** Though I did not write this code, I did convert it to a gem and I'm currently the sole owner on
6
+ rubygems. With Joel Chippindale's approval I've taken over defacto maintainership of this gem. My use case is
7
+ primarily under rails 3, and the current version is not backwards compatible, but I will maintain a 2.3.x branch as well
8
+ if anyone has patches.
9
+
10
+ # CSV Builder
11
+
12
+ The CSV Builder Rails plugin provides a simple templating system for serving dynamically generated CSV files from your
13
+ application.
14
+
15
+
16
+
17
+ ## Requirements
18
+
19
+ The current version of CSV Builder works with:
20
+
21
+ * Rails 3.x
22
+ * Ruby 1.8 or 1.9
23
+
24
+ The legacy version (1.1.x) was originally developed and tested for Rails 2.1. See [the legacy
25
+ docs](https://github.com/econsultancy/csv_builder) for more details.
26
+
27
+
28
+
29
+ ## Install
30
+
31
+ ### Install as a gem (recommended)
32
+
33
+ $ gem install csv_builder
34
+
35
+ If you are using Bundler then [you know what to do](http://gembundler.com).
36
+
37
+
38
+
39
+ ## Example
40
+
41
+ CSV template files are suffixed with `.csv.csvbuilder`, for example `index.csv.csvbuilder`
42
+
43
+ Add rows to your CSV file in the template by pushing arrays of columns into the csv object.
44
+
45
+ # First row
46
+ csv << [ 'cell 1', 'cell 2' ]
47
+ # Second row
48
+ csv << [ 'another cell value', 'and another' ]
49
+ # etc...
50
+
51
+ You can set the default filename for that a browser will use for 'save as' by setting `@filename` instance variable in
52
+ your controller's action method e.g.
53
+
54
+ @filename = 'report.csv'
55
+
56
+ You can set the input encoding and output encoding by setting `@input_encoding` and `@output_encoding` instance
57
+ variables. These default to 'UTF-8' and 'LATIN1' respectively. e.g.
58
+
59
+ @output_encoding = 'UTF-8'
60
+
61
+ You can set `@csv_options` instance variable to define options for FasterCSV generator. For example:
62
+
63
+ @csv_options = { :force_quotes => true, :col_sep => ';' }
64
+
65
+ You can respond with csv in your controller as well:
66
+
67
+ respond_to do |format|
68
+ format.html
69
+ format.csv # make sure you have action_name.csv.csvbuilder template in place
70
+ end
71
+
72
+ You can also attach a csv file to mail sent out by your application by
73
+ including a snippet like the following in your mailer method
74
+
75
+ attachment "text/csv" do |attachment|
76
+ attachment.body = render(:file => 'example/index.csv.csvbuilder')
77
+ attachment.filename = 'report.csv'
78
+ end
79
+
80
+
81
+
82
+ ## Contributions
83
+
84
+ As of version 2.0 this gem has a rudimentary spec suite for Rails 3. The test suite has been run under both Ruby 1.8
85
+ and 1.9. The requirements are in the Gemfile within the test spec directory. You will need Bundler installed and then
86
+ you can run:
87
+
88
+ cd spec/rails_app && bundle install && cd ../..
89
+
90
+ To install the main testing requirements. Then return back to the root directory and run:
91
+
92
+ rake spec
93
+
94
+ I will also take patches for Rails 2.3.x, though I personally have no further need of that branch.
95
+
96
+
97
+
98
+ ## Troubleshooting
99
+
100
+ There's a known bug of encoding error in Ruby 1.9
101
+
102
+ For more details see https://rails.lighthouseapp.com/projects/8994/tickets/2188-i18n-fails-with-multibyte-strings-in-ruby-19-similar-to-2038
103
+
104
+
105
+ Copyright (c) 2008 Econsultancy.com, 2009 Vidmantas Kabošis & 2011 Gabe da Silveira released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1,47 @@
1
+ require 'rake/rdoctask'
2
+ require 'rspec/core'
3
+ require 'rspec/core/rake_task'
4
+ require 'jeweler'
5
+
6
+ desc 'Generate documentation for the csv_builder plugin.'
7
+ Rake::RDocTask.new(:rdoc) do |rdoc|
8
+ rdoc.rdoc_dir = 'rdoc'
9
+ rdoc.title = 'CSV Builder'
10
+ rdoc.options << '--line-numbers' << '--inline-source'
11
+ rdoc.rdoc_files.include('README.rdoc')
12
+ rdoc.rdoc_files.include('CHANGELOG.rdoc')
13
+ rdoc.rdoc_files.include('lib/**/*.rb')
14
+ end
15
+
16
+ desc 'Test the csv builder'
17
+ RSpec::Core::RakeTask.new(:spec) do |t|
18
+ t.pattern = "./spec/**/*_spec.rb"
19
+ end
20
+
21
+ desc 'Default: run specs.'
22
+ task :default => :spec
23
+
24
+ Jeweler::Tasks.new do |gem|
25
+ gem.name = "csv_builder"
26
+ gem.homepage = "http://github.com/dasil003/csv_builder"
27
+ gem.license = "MIT"
28
+ gem.summary = %Q{CSV template handler for Rails}
29
+ gem.description = %Q{CSV template handler for Rails. Enables :format => 'csv' in controllers, with templates of the form report.csv.csvbuilder.}
30
+ gem.email = "gabe@websaviour.com"
31
+ gem.authors = ['Econsultancy', 'Vidmantas Kabosis', "Gabe da Silveira"]
32
+
33
+ gem.files.exclude 'spec'
34
+
35
+ gem.add_dependency 'actionpack', '>=3.0.0'
36
+
37
+ gem.add_development_dependency 'rails', '>= 3.0.0'
38
+ gem.add_development_dependency 'rspec', '~> 2.5'
39
+ gem.add_development_dependency 'rspec-rails', '~> 2.5'
40
+ gem.add_development_dependency 'jeweler'
41
+ gem.add_development_dependency 'rack'
42
+ gem.add_development_dependency 'sqlite3'
43
+
44
+ gem.requirements << 'iconv'
45
+ gem.requirements << 'Ruby 1.9.x or FasterCSV'
46
+ end
47
+ Jeweler::RubygemsDotOrgTasks.new
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 2.0.1
@@ -0,0 +1,5 @@
1
+ class CsvBuilder::Railtie < Rails::Railtie
2
+ initializer "csv_builder.register_template_handler.action_view" do
3
+ ActionView::Template.register_template_handler 'csvbuilder', CsvBuilder::StreamingTemplateHandler
4
+ end
5
+ end
@@ -0,0 +1,123 @@
1
+ # encoding: utf-8
2
+
3
+ module CsvBuilder # :nodoc:
4
+
5
+ class Yielder
6
+ def initialize(stream_proc)
7
+ @stream_proc = stream_proc
8
+ end
9
+
10
+ def pos
11
+ return 0
12
+ end
13
+
14
+ def eof?
15
+ return true
16
+ end
17
+
18
+ def rewind
19
+ end
20
+
21
+ def read(arg1)
22
+ return "\n"
23
+ end
24
+
25
+ def <<(data)
26
+ @stream_proc.call data
27
+ end
28
+
29
+ end
30
+
31
+ class Streamer
32
+ def initialize(template_proc)
33
+ @template_proc = template_proc
34
+ end
35
+
36
+ def each
37
+ # The ruby csv class will try to infer a separator to use, if the csv options
38
+ # do not set it. ruby's csv calls pos, eof?, read, and rewind to check the first line
39
+ # of the io to infer a separator. Rails' output object does not support these methods
40
+ # so we provide a mock implementation to satisfy csv.
41
+ #
42
+ # See code at https://github.com/ruby/ruby/blob/trunk/lib/csv.rb#L2021 - note that @io points
43
+ # to the output variable defined by this block.
44
+ # output.class.send(:define_method, "pos") {return 0 }
45
+ # output.class.send(:define_method, "eof?") { return true }
46
+ # output.class.send(:define_method, "rewind") {}
47
+ # read needs to return a newline, otherwise csv loops indefinitely looking for the end of the first line.
48
+ # output.class.send(:define_method, "read") {|arg1| return "\\n" }
49
+ # output = ""
50
+ # The ruby csv write method requires output to support << for writing. Here we just
51
+ # delegate the method call to output's write method.
52
+ # output.class.send(:define_method, "<<") {|arg1| yield arg1}
53
+
54
+ yielder = CsvBuilder::Yielder.new(Proc.new{|data| yield data})
55
+ csv_stream = CsvBuilder::CSV_LIB.new(yielder, @csv_options || {})
56
+ csv = CsvBuilder::TransliteratingFilter.new(csv_stream, @input_encoding || 'UTF-8', @output_encoding || 'LATIN1')
57
+ @template_proc.call(csv)
58
+ end
59
+ end
60
+ # Template handler for csv templates
61
+ #
62
+ # Add rows to your CSV file in the template by pushing arrays of columns into csv
63
+ #
64
+ # # First row
65
+ # csv << [ 'cell 1', 'cell 2' ]
66
+ # # Second row
67
+ # csv << [ 'another cell value', 'and another' ]
68
+ # # etc...
69
+ #
70
+ # You can set the default filename for that a browser will use for 'save as' by
71
+ # setting <tt>@filename</tt> instance variable in your controller's action method
72
+ # e.g.
73
+ #
74
+ # @filename = 'report.csv'
75
+ #
76
+ # You can also set the input encoding and output encoding by setting
77
+ # <tt>@input_encoding</tt> and <tt>@output_encoding</tt> instance variables.
78
+ # These default to 'UTF-8' and 'LATIN1' respectively. e.g.
79
+ #
80
+ # @output_encoding = 'UTF-8'
81
+ class StreamingTemplateHandler < ActionView::Template::Handler
82
+ include ActionView::Template::Handlers::Compilable
83
+
84
+ def compile(template)
85
+
86
+ <<-EOV
87
+ begin
88
+
89
+ unless defined?(ActionMailer) && defined?(ActionMailer::Base) && controller.is_a?(ActionMailer::Base)
90
+ @filename ||= "\#{controller.action_name}.csv"
91
+ if controller.request.env['HTTP_USER_AGENT'] =~ /msie/i
92
+ response.headers['Pragma'] = 'public'
93
+ response.headers["Content-type"] = "text/plain"
94
+ response.headers['Cache-Control'] = 'no-cache, must-revalidate, post-check=0, pre-check=0'
95
+ response.headers['Content-Disposition'] = "attachment; filename=\#{@filename}"
96
+ response.headers['Expires'] = "0"
97
+ else
98
+ response.headers["Content-Type"] ||= 'text/csv'
99
+ response.headers["Content-Disposition"] = "attachment; filename=\#{@filename}"
100
+ response.headers["Content-Transfer-Encoding"] = "binary"
101
+ end
102
+ end
103
+
104
+ if @streaming
105
+ template = Proc.new {|csv|
106
+ #{template.source}
107
+ }
108
+ CsvBuilder::Streamer.new(template)
109
+ else
110
+ output = CsvBuilder::CSV_LIB.generate(@csv_options || {}) do |faster_csv|
111
+ csv = CsvBuilder::TransliteratingFilter.new(faster_csv, @input_encoding || 'UTF-8', @output_encoding || 'LATIN1')
112
+ #{template.source}
113
+ end
114
+ output
115
+ end
116
+ rescue Exception => e
117
+ Rails.logger.warn("Exception \#{e} \#{e.message} with class \#{e.class.name} thrown when rendering CSV")
118
+ raise e
119
+ end
120
+ EOV
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,23 @@
1
+ #encoding: utf-8
2
+
3
+ class CsvBuilder::TransliteratingFilter
4
+ # Transliterate into the required encoding if necessary
5
+ def initialize(faster_csv, input_encoding = 'UTF-8', output_encoding = 'LATIN1')
6
+ @faster_csv = faster_csv
7
+
8
+ # TODO: do some checking to make sure iconv works correctly in
9
+ # current environment. See ActiveSupport::Inflector#transliterate
10
+ # definition for details
11
+ #
12
+ # Not using the more standard //IGNORE//TRANSLIT because it raises
13
+ # Iconv::IllegalSequence for some inputs
14
+ @iconv = Iconv.new("#{output_encoding}//TRANSLIT//IGNORE", input_encoding) if input_encoding != output_encoding
15
+ end
16
+
17
+ # Transliterate before passing to FasterCSV so that the right characters (e.g. quotes) get escaped
18
+ def <<(row)
19
+ @faster_csv << if @iconv then row.map { |value| @iconv.iconv(value.to_s) } else row end
20
+ end
21
+
22
+ alias :add_row :<<
23
+ end
@@ -0,0 +1,17 @@
1
+ # encoding: utf-8
2
+
3
+ module CsvBuilder
4
+ if RUBY_VERSION.to_f >= 1.9
5
+ require 'csv'
6
+ CSV_LIB = CSV
7
+ else
8
+ require 'fastercsv'
9
+ CSV_LIB = FasterCSV
10
+ end
11
+ end
12
+
13
+ require 'action_view'
14
+ require 'iconv'
15
+ require 'csv_builder/transliterating_filter'
16
+ require 'csv_builder/template_handler'
17
+ require 'csv_builder/railtie'
data/rails/init.rb ADDED
@@ -0,0 +1,3 @@
1
+ require 'csv_builder'
2
+
3
+ ActionView::Template.register_template_handler 'csvbuilder', CsvBuilder::StreamingTemplateHandler
metadata ADDED
@@ -0,0 +1,138 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: csv_streamer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Econsultancy
9
+ - Vidmantas Kabosis
10
+ - Gabe da Silveira
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2011-05-24 00:00:00.000000000Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: actionpack
18
+ requirement: &2157673820 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ! '>='
22
+ - !ruby/object:Gem::Version
23
+ version: 3.0.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *2157673820
27
+ - !ruby/object:Gem::Dependency
28
+ name: rails
29
+ requirement: &2157673320 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ! '>='
33
+ - !ruby/object:Gem::Version
34
+ version: 3.0.0
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: *2157673320
38
+ - !ruby/object:Gem::Dependency
39
+ name: rspec
40
+ requirement: &2157672840 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.5'
46
+ type: :development
47
+ prerelease: false
48
+ version_requirements: *2157672840
49
+ - !ruby/object:Gem::Dependency
50
+ name: rspec-rails
51
+ requirement: &2157672340 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: '2.5'
57
+ type: :development
58
+ prerelease: false
59
+ version_requirements: *2157672340
60
+ - !ruby/object:Gem::Dependency
61
+ name: jeweler
62
+ requirement: &2157671860 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ! '>='
66
+ - !ruby/object:Gem::Version
67
+ version: '0'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: *2157671860
71
+ - !ruby/object:Gem::Dependency
72
+ name: rack
73
+ requirement: &2157671360 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ! '>='
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: *2157671360
82
+ - !ruby/object:Gem::Dependency
83
+ name: sqlite3
84
+ requirement: &2157670860 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ! '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: *2157670860
93
+ description: CSV template handler for Rails. Enables :format => 'csv' in controllers,
94
+ with templates of the form report.csv.csvbuilder.
95
+ email: gabe@websaviour.com
96
+ executables: []
97
+ extensions: []
98
+ extra_rdoc_files:
99
+ - README.md
100
+ files:
101
+ - CHANGELOG.rdoc
102
+ - MIT-LICENSE
103
+ - README.md
104
+ - Rakefile
105
+ - VERSION
106
+ - lib/csv_builder.rb
107
+ - lib/csv_builder/railtie.rb
108
+ - lib/csv_builder/template_handler.rb
109
+ - lib/csv_builder/transliterating_filter.rb
110
+ - rails/init.rb
111
+ homepage: http://github.com/dasil003/csv_builder
112
+ licenses:
113
+ - MIT
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ none: false
120
+ requirements:
121
+ - - ! '>='
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ required_rubygems_version: !ruby/object:Gem::Requirement
125
+ none: false
126
+ requirements:
127
+ - - ! '>='
128
+ - !ruby/object:Gem::Version
129
+ version: '0'
130
+ requirements:
131
+ - iconv
132
+ - Ruby 1.9.x or FasterCSV
133
+ rubyforge_project:
134
+ rubygems_version: 1.8.7
135
+ signing_key:
136
+ specification_version: 3
137
+ summary: CSV template handler for Rails
138
+ test_files: []