jsanders-ruport 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (76) hide show
  1. data/AUTHORS +48 -0
  2. data/LICENSE +59 -0
  3. data/README +114 -0
  4. data/Rakefile +93 -0
  5. data/examples/RWEmerson.jpg +0 -0
  6. data/examples/anon.rb +43 -0
  7. data/examples/btree/commaleon/commaleon.rb +263 -0
  8. data/examples/btree/commaleon/sample_data/ticket_count.csv +124 -0
  9. data/examples/btree/commaleon/sample_data/ticket_count2.csv +119 -0
  10. data/examples/centered_pdf_text_box.rb +83 -0
  11. data/examples/data/tattle.dump +82 -0
  12. data/examples/example.csv +3 -0
  13. data/examples/line_plotter.rb +61 -0
  14. data/examples/pdf_report_with_common_base.rb +72 -0
  15. data/examples/png_embed.rb +54 -0
  16. data/examples/roadmap.png +0 -0
  17. data/examples/row_renderer.rb +39 -0
  18. data/examples/simple_pdf_lines.rb +25 -0
  19. data/examples/simple_templating_example.rb +34 -0
  20. data/examples/tattle_ruby_version.rb +39 -0
  21. data/examples/tattle_rubygems_version.rb +37 -0
  22. data/examples/trac_ticket_status.rb +59 -0
  23. data/lib/ruport.rb +127 -0
  24. data/lib/ruport/controller.rb +616 -0
  25. data/lib/ruport/controller/grouping.rb +71 -0
  26. data/lib/ruport/controller/table.rb +54 -0
  27. data/lib/ruport/data.rb +4 -0
  28. data/lib/ruport/data/feeder.rb +111 -0
  29. data/lib/ruport/data/grouping.rb +399 -0
  30. data/lib/ruport/data/record.rb +297 -0
  31. data/lib/ruport/data/table.rb +950 -0
  32. data/lib/ruport/extensions.rb +4 -0
  33. data/lib/ruport/formatter.rb +254 -0
  34. data/lib/ruport/formatter/csv.rb +149 -0
  35. data/lib/ruport/formatter/html.rb +161 -0
  36. data/lib/ruport/formatter/pdf.rb +591 -0
  37. data/lib/ruport/formatter/template.rb +187 -0
  38. data/lib/ruport/formatter/text.rb +231 -0
  39. data/lib/uport.rb +1 -0
  40. data/test/controller_test.rb +743 -0
  41. data/test/csv_formatter_test.rb +164 -0
  42. data/test/data_feeder_test.rb +88 -0
  43. data/test/grouping_test.rb +410 -0
  44. data/test/helpers.rb +11 -0
  45. data/test/html_formatter_test.rb +201 -0
  46. data/test/pdf_formatter_test.rb +354 -0
  47. data/test/record_test.rb +332 -0
  48. data/test/samples/addressbook.csv +6 -0
  49. data/test/samples/data.csv +3 -0
  50. data/test/samples/data.tsv +3 -0
  51. data/test/samples/dates.csv +1409 -0
  52. data/test/samples/erb_test.sql +1 -0
  53. data/test/samples/query_test.sql +1 -0
  54. data/test/samples/ruport_test.sql +8 -0
  55. data/test/samples/test.sql +2 -0
  56. data/test/samples/test.yaml +3 -0
  57. data/test/samples/ticket_count.csv +124 -0
  58. data/test/table_pivot_test.rb +134 -0
  59. data/test/table_test.rb +838 -0
  60. data/test/template_test.rb +48 -0
  61. data/test/text_formatter_test.rb +258 -0
  62. data/util/bench/data/record/bench_as_vs_to.rb +18 -0
  63. data/util/bench/data/record/bench_constructor.rb +46 -0
  64. data/util/bench/data/record/bench_indexing.rb +65 -0
  65. data/util/bench/data/record/bench_reorder.rb +35 -0
  66. data/util/bench/data/record/bench_to_a.rb +19 -0
  67. data/util/bench/data/table/bench_column_manip.rb +103 -0
  68. data/util/bench/data/table/bench_dup.rb +24 -0
  69. data/util/bench/data/table/bench_init.rb +67 -0
  70. data/util/bench/data/table/bench_manip.rb +125 -0
  71. data/util/bench/formatter/bench_csv.rb +14 -0
  72. data/util/bench/formatter/bench_html.rb +14 -0
  73. data/util/bench/formatter/bench_pdf.rb +14 -0
  74. data/util/bench/formatter/bench_text.rb +14 -0
  75. data/util/bench/samples/tattle.csv +1237 -0
  76. metadata +176 -0
data/AUTHORS ADDED
@@ -0,0 +1,48 @@
1
+ = Developers
2
+
3
+ - {Gregory Brown}[mailto:gregory.t.brown@gmail.com]
4
+ - {Dudley Flanders}[mailto:dudley@misnomer.us]
5
+ - {James Healy}[mailto:jimmy@deefa.com]
6
+ - Dinko Mehinovic
7
+ - {Michael Milner}[mailto:mikem836@gmail.com]
8
+
9
+ = Contributors / People we've (legally) stolen from:
10
+
11
+ Iain Broadfoot:
12
+ - RuportDay 2006 Participant
13
+
14
+ Eric Pugh:
15
+ - RuportDay 2006 Participant
16
+
17
+ James Edward Gray II:
18
+ - Original inspiration via query.rb
19
+ - system_extensions.rb
20
+
21
+ Mathijs Mohlmann:
22
+ - Performance Enhancement
23
+ TextPlugin r264-r265
24
+ HTMLPlugin r266
25
+
26
+ Francis Hwang:
27
+ - SQLSplit
28
+
29
+ Simon Claret:
30
+ - Initial PDF table support (now deprecated)
31
+
32
+ Daniel Berger:
33
+ - we vendored and modified attempt.rb to support it directly in Report.
34
+ Original website: http://raa.ruby-lang.org/project/attempt/
35
+
36
+ Marshall T. Vandegrift:
37
+ - Fixed a bug in Record's struct-like accessors (method_missing)
38
+ - Provided performance enhancements and tests for query.rb
39
+ - Improved alignment for Text Tables.
40
+
41
+ Stefan Mahlitz:
42
+ - Table#sort_rows_by
43
+
44
+ Chris Carter
45
+ - Table#remove_columns (r440)
46
+
47
+ Dave Nelson
48
+ - Grouping#sigma (r1131)
data/LICENSE ADDED
@@ -0,0 +1,59 @@
1
+ Ruport is copyrighted free software originally produced by Gregory Brown
2
+ <gregory.t.brown@gmail.com> which now contains a number of community
3
+ contributions and is actively developed by Michael Milner <mikem836@gmail.com>.
4
+
5
+ See the AUTHORS file for a complete list of contributors.
6
+
7
+ Licensing terms follow (License of Ruby 1.8):
8
+
9
+ You can redistribute Ruport and/or modify it under either the terms of the GPL
10
+ (see COPYING file), or the conditions below:
11
+
12
+ 1. You may make and give away verbatim copies of the source form of the
13
+ software without restriction, provided that you duplicate all of the
14
+ original copyright notices and associated disclaimers.
15
+
16
+ 2. You may modify your copy of the software in any way, provided that
17
+ you do at least ONE of the following:
18
+
19
+ a) place your modifications in the Public Domain or otherwise
20
+ make them Freely Available, such as by posting said
21
+ modifications to Usenet or an equivalent medium, or by allowing
22
+ the author to include your modifications in the software.
23
+
24
+ b) use the modified software only within your corporation or
25
+ organization.
26
+
27
+ c) rename any non-standard executables so the names do not conflict
28
+ with standard executables, which must also be provided.
29
+
30
+ d) make other distribution arrangements with the author.
31
+
32
+ 3. You may distribute the software in object code or executable
33
+ form, provided that you do at least ONE of the following:
34
+
35
+ a) distribute the executables and library files of the software,
36
+ together with instructions (in the manual page or equivalent)
37
+ on where to get the original distribution.
38
+
39
+ b) accompany the distribution with the machine-readable source of
40
+ the software.
41
+
42
+ c) give non-standard executables non-standard names, with
43
+ instructions on where to get the original software distribution.
44
+
45
+ d) make other distribution arrangements with the author.
46
+
47
+ 4. You may modify and include the part of the software into any other
48
+ software (possibly commercial).
49
+
50
+ 5. The scripts and library files supplied as input to or produced as
51
+ output from the software do not automatically fall under the
52
+ copyright of the software, but belong to whomever generated them,
53
+ and may be sold commercially, and may be aggregated with this
54
+ software.
55
+
56
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
57
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
58
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
59
+ PURPOSE.
data/README ADDED
@@ -0,0 +1,114 @@
1
+ # -----------------------------------------------------------------
2
+ # Contents:
3
+ #
4
+ # + What Ruport Is
5
+ # + Installation
6
+ # + Resources
7
+ # + Hacking
8
+ #
9
+ # = What Ruport Is
10
+ #
11
+ # Ruby Reports (Ruport) is an extensible reporting system.
12
+ #
13
+ # It aims to be as lightweight as possible while still providing core support
14
+ # for data aggregation and manipulation as well as multi-format rendering
15
+ # of reports.
16
+ #
17
+ # Ruport provides tools for using a number of data sources, including CSV files,
18
+ # ActiveRecord models, and raw SQL connections via RubyDBI (through ruport-util).
19
+ #
20
+ # Data manipulation is easy as there are standard structures that support
21
+ # record, table, and grouping operations. These all can be extended to
22
+ # implement custom behavior as needed.
23
+ #
24
+ # For common tasks, Ruport provides formatters for CSV, HTML, PDF, and text-
25
+ # based reports. However, the real power lies in building custom report
26
+ # controllers and formatters. The base formatting libraries provide a number
27
+ # of helper functions that will let you build complex reports while maintaining
28
+ # a DRY and consistent interface.
29
+ #
30
+ # To get a quick feel for what you can accomplish with Ruport, take a look at
31
+ # a few simple examples provided on our web site.
32
+ #
33
+ # http://rubyreports.org/examples.html
34
+ #
35
+ # Since Ruport's core support is intentionally minimalistic, you may be looking
36
+ # for some higher level support for specific needs such as graphing, invoices,
37
+ # report mailing support, etc. For this, you may wish to take a look at the
38
+ # ruport-util package, which contains some generally useful tools and libraries
39
+ # to extend Ruport's capabilities.
40
+ #
41
+ # = Installation
42
+ #
43
+ # To install ruport via rubygems:
44
+ #
45
+ # sudo gem install ruport
46
+ #
47
+ # Check to see if it installed properly:
48
+ #
49
+ # ruby -rubygems -e "require 'ruport'; puts Ruport::VERSION"
50
+ #
51
+ # If you get an error, please let us know on our mailing list.
52
+ #
53
+ # Dependencies Details:
54
+ #
55
+ # -- formatting
56
+ #
57
+ # Ruport relies on PDF::Writer and FasterCSV for its formatting support.
58
+ # If you want to make use of textile helpers, you'll also need RedCloth.
59
+ #
60
+ # -- database interaction
61
+ #
62
+ # If you wish to use Ruport to report against a rails project,
63
+ # a camping project, or do standalone acts_as_reportable reports, you'll need
64
+ # ActiveRecord and the acts_as_reportable gem.
65
+ #
66
+ # If you want to use Ruport::Query for raw SQL support, you'll need to
67
+ # install ruport-util, RubyDBI and whatever database drivers you might need.
68
+ #
69
+ # = Resources
70
+ #
71
+ # Our developers have published a free-content book about all things
72
+ # Ruport, including complete coverage of acts_as_reportable and some of
73
+ # ruport-util's features. This book serves as the definitive guide to
74
+ # Ruport, so all users should become acquainted with it:
75
+ #
76
+ # http://ruportbook.com
77
+ #
78
+ # The next best way to get help and make suggestions is the Ruport mailing list.
79
+ # This software is on the move, so the list is the most reliable way of getting
80
+ # up to date information.
81
+ #
82
+ # - You can sign up and/or view the archives here:
83
+ # http://groups.google.com/group/ruby-reports
84
+ #
85
+ # If you are looking to dig a little deeper, there are a couple more resources
86
+ # that may be helpful to you.
87
+ #
88
+ # - The latest stable API documentation is available at:
89
+ # http://api.rubyreports.org
90
+ #
91
+ # - Our Trac is at: http://code.rubyreports.org/ruport
92
+ # You may use the username ruport and password blinky to file tickets.
93
+ #
94
+ # = Hacking
95
+ #
96
+ # If you'd like to contribute code to Ruport, please join our development
97
+ # mailing list, and let us know what you'd like to do!
98
+ #
99
+ # http://groups.google.com/group/ruport-dev
100
+ #
101
+ # It also may be worthwhile to join this list if you plan on running edge
102
+ # versions of Ruport, as this is where we make announcements about major
103
+ # breakage in trunk.
104
+ #
105
+ # We are very responsive to contributors, and review every patch we receive
106
+ # fairly quickly. Most contributors who successfully get a patch or two applied
107
+ # are given write access to the repositories and invited to join Ruport's
108
+ # development team. Since we view every user as potential contributor, this
109
+ # approach works well for us.
110
+ #
111
+ # So if you want to help out with Ruport, we'll happy accept your efforts!
112
+
113
+
114
+
data/Rakefile ADDED
@@ -0,0 +1,93 @@
1
+ require "rake/rdoctask"
2
+ require "rake/testtask"
3
+
4
+ RUPORT_VERSION = "1.7.0"
5
+
6
+ begin
7
+ require "rubygems"
8
+ rescue LoadError
9
+ nil
10
+ end
11
+
12
+ task :default => [:test]
13
+
14
+ Rake::TestTask.new do |test|
15
+ test.libs << "test"
16
+ test.test_files = Dir[ "test/*_test.rb" ]
17
+ test.verbose = true
18
+ end
19
+
20
+ Rake::RDocTask.new do |rdoc|
21
+ rdoc.rdoc_files.include( "README",
22
+ #"CHANGELOG",
23
+ "AUTHORS", "COPYING",
24
+ "LICENSE", "lib/" )
25
+ rdoc.main = "README"
26
+ rdoc.rdoc_dir = "doc/html"
27
+ rdoc.title = "Ruport Documentation"
28
+ end
29
+
30
+ task :build_archives => [:package,:rcov,:rdoc] do
31
+ mv "pkg/ruport-#{RUPORT_VERSION}.tgz", "pkg/ruport-#{RUPORT_VERSION}.tar.gz"
32
+ sh "tar cjvf pkg/ruport_coverage-#{RUPORT_VERSION}.tar.bz2 coverage"
33
+ sh "tar cjvf pkg/ruport_doc-#{RUPORT_VERSION}.tar.bz2 doc/html"
34
+ cd "pkg"
35
+ sh "tar cjvf ruport-#{RUPORT_VERSION}.tar.bz2 ruport-#{RUPORT_VERSION}"
36
+ end
37
+
38
+ task :run_benchmarks do
39
+ files = FileList["util/bench/**/**/*.rb"]
40
+ files.sort!
41
+ files.uniq!
42
+ names = files.map { |r| r.sub("util/bench","").split("/").map { |e| e.capitalize } }
43
+ names.map! { |e| e[1..-2].join("::") + " <BENCH: #{e[-1].sub('Bench_','').sub('.rb','')}>" }
44
+ start_time = Time.now
45
+ files.zip(names).each { |f,n|
46
+ puts "\n#{n}\n\n"
47
+ sh "ruby -Ilib #{f}"
48
+ puts "\n"
49
+ }
50
+ end_time = Time.now
51
+ puts "\n** Total Run Time: #{end_time-start_time}s **"
52
+ end
53
+
54
+ begin
55
+ require 'rcov/rcovtask'
56
+ Rcov::RcovTask.new do |t|
57
+ t.test_files = Dir[ "test/*_test.rb" ]
58
+ end
59
+ rescue LoadError
60
+ nil
61
+ end
62
+
63
+ begin
64
+ require 'jeweler'
65
+ Jeweler::Tasks.new do |s|
66
+ s.name = "ruport"
67
+ s.version = RUPORT_VERSION
68
+ s.platform = Gem::Platform::RUBY
69
+ s.summary = "A generalized Ruby report generation and templating engine."
70
+ s.files = Dir.glob("{examples,lib,test,bin,util/bench}/**/**/*") +
71
+ ["Rakefile"]
72
+ s.require_path = "lib"
73
+
74
+ s.test_files = Dir[ "test/*_test.rb" ]
75
+ s.has_rdoc = true
76
+ s.extra_rdoc_files = %w{README LICENSE AUTHORS}
77
+ s.rdoc_options << '--title' << 'Ruport Documentation' <<
78
+ '--main' << 'README' << '-q'
79
+ s.add_dependency('fastercsv')
80
+ s.add_dependency('pdf-writer','= 1.1.8')
81
+ s.author = "Gregory Brown"
82
+ s.email = " gregory.t.brown@gmail.com"
83
+ s.rubyforge_project = "ruport"
84
+ s.homepage = "http://rubyreports.org"
85
+ s.description = <<-END_DESC
86
+ Ruby Reports is a software library that aims to make the task of reporting
87
+ less tedious and painful. It provides tools for data acquisition,
88
+ database interaction, formatting, and parsing/munging.
89
+ END_DESC
90
+ end
91
+ rescue LoadError
92
+ puts 'Jeweler not available. Install it with: sudo gem install technicalpickles-jeweler -s http://gems.github.com'
93
+ end
Binary file
data/examples/anon.rb ADDED
@@ -0,0 +1,43 @@
1
+ # Demonstrates building a parent controller which provides additional 'built in'
2
+ # formats, allowing anonymous formatter support to use the simple interface
3
+ # rather than the :format => FormatterClass approach.
4
+
5
+ require "ruport"
6
+ module FooCorp
7
+ class Controller < Ruport::Controller
8
+ def self.built_in_formats
9
+ super.merge(:xml => FooCorp::Formatter::XML)
10
+ end
11
+ end
12
+
13
+ class Formatter
14
+ class XML < Ruport::Formatter
15
+
16
+ def xmlify(stuff)
17
+ output << "Wouldn't you like to see #{stuff} in XML?"
18
+ end
19
+ end
20
+ end
21
+
22
+ class MyController < FooCorp::Controller
23
+ stage :foo
24
+
25
+ formatter :xml do
26
+ build :foo do
27
+ xmlify "Red Snapper"
28
+ end
29
+ end
30
+
31
+ formatter :text do
32
+ build :foo do
33
+ output << "Red Snapper"
34
+ end
35
+ end
36
+ end
37
+ end
38
+
39
+ puts "XML:"
40
+ puts FooCorp::MyController.render_xml
41
+
42
+ puts "Text:"
43
+ puts FooCorp::MyController.render_text
@@ -0,0 +1,263 @@
1
+ # This example is a simplified version of a tool actually used at BTree.
2
+ # It does a very basic task:
3
+ #
4
+ # Given a master CSV file and a key column, it will compare the file
5
+ # to another CSV, and report back what is missing in the second CSV
6
+ # that was in the first, as well as what is changed in the second CSV
7
+ # based on the first.
8
+ #
9
+ # It is not bidirectional, and is mostly meant to compare snapshots
10
+ # of CSV dumps to see what has been removed or altered (we don't care
11
+ # about new records )
12
+ #
13
+ # It's a camping app, but the core of it is a controller/formatter combo.
14
+ # (Marked by %%%%%%%%%%% below)
15
+ #
16
+ # You'll need the camping omnibus and the F() ruport plugin to run this app.
17
+ #
18
+ # gem install camping-omnibus --source http://code.whytheluckystiff.net -y
19
+ # gem install f --source http://gems.rubyreports.org
20
+ #
21
+ # Once you have them, just run camping commaleon.rb and browse to
22
+ # http://localhost:3301
23
+ #
24
+ # Use ticket_count.csv as your master file and ticket_count2.csv as your
25
+ # comparison file. Use title as your key.
26
+ #
27
+ # Try out the different outputs, and tweak the app if you'd like to play
28
+ # with it.
29
+ #
30
+ # If your company has a need for tiny hackish camping/ruport amalgams,
31
+ # you can always ask Gregory if he's looking for work:
32
+ # <gregory.t.brown at gmail.com>
33
+ #
34
+ require "rubygems"
35
+ require "camping"
36
+ require "camping/session"
37
+ require "ruport"
38
+ require "ruport/extensions"
39
+
40
+ Camping.goes :Commaleon
41
+
42
+ module Commaleon
43
+ include Camping::Session
44
+ end
45
+
46
+ def Commaleon.create
47
+ Camping::Models::Session.create_schema
48
+ end
49
+
50
+ module Commaleon::Helpers
51
+
52
+ # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
53
+ # This is the bulk of the Ruport code in this app
54
+ # (CSVDiffController and CSVDiffFormatter)
55
+ # The rest is just camping. The interesting thing here is that
56
+ # you could easily define these in another file and just require
57
+ # them here, and use them standalone outside of your web app.
58
+ # %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
59
+
60
+ class CSVDiffController < Ruport::Controller
61
+ stage :diff_report
62
+ option :key, :mcsv, :ccsv
63
+
64
+ # This setup() idiom has become the default way of doing some
65
+ # manipulations on the data and options before handing off the
66
+ # rendering task to the formatters.
67
+ #
68
+ # We're using grouping mainly for the controller support,
69
+ # and rather than reducing a table, we're building up the
70
+ # group objects via the helper methods missing_from_compare
71
+ # and different_from_compare
72
+ def setup
73
+ @master_table = Table(:string => mcsv)
74
+ @compare_table = Table(:string => ccsv)
75
+ options.diff_report = Grouping(:by => "issue")
76
+ options.diff_report << missing_from_compare
77
+ options.diff_report << different_from_compare
78
+ end
79
+
80
+ # pulls the rows that are present in the master csv but not
81
+ # in the comparison csv and returns a group.
82
+ def missing_from_compare
83
+ missing_data = @master_table.rows_with(key) do |k|
84
+ missing_keys.include?(k)
85
+ end
86
+
87
+ Group("missing from main csv",
88
+ :data => missing_data,
89
+ :column_names => @master_table.column_names )
90
+ end
91
+
92
+ # pulls the rows that are present in the master csv but match
93
+ # a row with the same key in the compare csv that do not have
94
+ # identical attributes. Returns a group
95
+ def different_from_compare
96
+ shared = master_keys & compare_keys
97
+ m = @master_table.rows_with(key) do |k|
98
+ shared.include?(k)
99
+ end
100
+
101
+ diff = m.reject do |r|
102
+ @compare_table.any? { |s| s == r }
103
+ end
104
+
105
+ diff.each do |r|
106
+ comp = @compare_table.rows_with(key => r[key])[0]
107
+ r.to_hash.each do |k,v|
108
+ v << " ## " << comp[k] unless v == comp[k]
109
+ end
110
+ end
111
+
112
+ Group("different from main csv",
113
+ :data => diff, :column_names => @master_table.column_names)
114
+ end
115
+
116
+ def missing_keys
117
+ master_keys - compare_keys
118
+ end
119
+
120
+ def master_keys
121
+ @master_table.column(key)
122
+ end
123
+
124
+ def compare_keys
125
+ @compare_table.column(key)
126
+ end
127
+ end
128
+
129
+ # This is using the F plugin which saves us a line of code and just
130
+ # looks neat, IMO
131
+ #
132
+ # For more details:
133
+ #
134
+ # http://stonecode.svnrepository.com/ruport/trac.cgi/wiki/F
135
+ #
136
+ class CSVDiffFormatter < F([:html,:text,:csv,:pdf], :for => CSVDiffController)
137
+ def build_diff_report
138
+ # this is using the selective blocks for formatters that implement
139
+ # more than one format. The block below will only be called when this
140
+ # formatter is rendering HTML
141
+ html { gussy_up_html }
142
+
143
+ render_grouping( options.diff_report,
144
+ :style => options.style || :inline )
145
+ end
146
+
147
+ # adds headers to group name to make the output a little prettier
148
+ def gussy_up_html
149
+ options.diff_report.each do |n,g|
150
+ g.send(:name=, "<h4>#{n}</h4>")
151
+ end
152
+ end
153
+ end
154
+
155
+ end
156
+
157
+ module Commaleon::Controllers
158
+
159
+ class Index < R "/"
160
+ def get
161
+ redirect R(CSVDifference)
162
+ end
163
+ end
164
+
165
+ class CSVDifference < R '/csv_diff'
166
+ def get
167
+ render :get_diff_files
168
+ end
169
+
170
+ def post
171
+ @state.mfile = @input.mfile.tempfile.read
172
+ @state.cfile = @input.cfile.tempfile.read
173
+ redirect R(GenerateDiffReport)
174
+ end
175
+ end
176
+
177
+ class GenerateDiffReport < R '/csv_diff/report'
178
+ def get
179
+ @id_fields = Table(:string=>@state.mfile).column_names &
180
+ Table(:string=>@state.cfile).column_names
181
+ render :csv_get_id
182
+ end
183
+
184
+ def post
185
+ @state.key = @input.csv_id
186
+ @table = CSVDiffController.render_html(:key => @state.key,
187
+ :mcsv => @state.mfile,
188
+ :ccsv => @state.cfile )
189
+ render :html_diff
190
+ end
191
+ end
192
+
193
+ class CSVDiffReportFormatted < R '/csv_diff/report.(.*)'
194
+ def set_headers(format)
195
+ types = { "csv" => "application/vnd.ms-excel",
196
+ "pdf" => "application/pdf",
197
+ "txt" => "text/plain" }
198
+ @headers["Content-Type"] = types[format]
199
+ @headers["Content-Disposition"] = "attachment; filename=diff.#{format}"
200
+ end
201
+
202
+ def get(format)
203
+ options = { :key => @state.key,
204
+ :mcsv => @state.mfile,
205
+ :ccsv => @state.cfile }
206
+
207
+ set_headers(format)
208
+ case(format)
209
+ when "csv"
210
+ text CSVDiffController.render_csv(options)
211
+ when "pdf"
212
+ text CSVDiffController.render_pdf(options.merge(:style => :justified))
213
+ when "txt"
214
+ text CSVDiffController.render_text(options)
215
+ else
216
+ text "no format!"
217
+ end
218
+ end
219
+ end
220
+
221
+ end
222
+
223
+ module Commaleon::Views
224
+ def get_diff_files
225
+ form :action => "?upload_id=#{Time.now.to_f}", :method => 'post',
226
+ :enctype => 'multipart/form-data' do
227
+ p do
228
+ label "Master File: ", :for => "mfile"
229
+ input({:name => "mfile", :type => 'file'})
230
+ end
231
+ p do
232
+ label "Comparison File: ", :for => "cfile"
233
+ input({:name => "cfile", :type => 'file'})
234
+ end
235
+ p do
236
+ input.newfile! :type => "submit", :value => "Upload"
237
+ end
238
+ end
239
+ end
240
+
241
+ def csv_get_id
242
+ form :method => "post" do
243
+ label "ID column: ", :for => "csv_id"
244
+ select(:name => "csv_id") do
245
+ @id_fields.each { |f| option(f) }
246
+ end
247
+ input :type => "submit", :value => "Set ID"
248
+ end
249
+ end
250
+
251
+ def html_diff
252
+ text @table
253
+ hr
254
+ ul do
255
+ li { a "New Diff", :href => R(CSVDifference) }
256
+ li { a "New Key for Diff", :href => R(GenerateDiffReport) }
257
+ li { a "CSV Download", :href => R(CSVDiffReportFormatted,"csv") }
258
+ li { a "Text Download", :href => R(CSVDiffReportFormatted,"txt") }
259
+ li { a "PDF Download", :href => R(CSVDiffReportFormatted,"pdf") }
260
+ end
261
+ end
262
+
263
+ end