csv_streamer 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.
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: []