ruport 0.8.0 → 0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. data/AUTHORS +1 -5
  2. data/README +4 -4
  3. data/Rakefile +2 -2
  4. data/examples/rope_examples/itunes/README +12 -0
  5. data/examples/rope_examples/itunes/Rakefile +18 -0
  6. data/examples/rope_examples/itunes/config/ruport_config.rb +8 -0
  7. data/examples/rope_examples/itunes/data/mix.txt +1 -0
  8. data/examples/rope_examples/itunes/lib/helpers.rb +0 -0
  9. data/examples/rope_examples/itunes/lib/init.rb +9 -0
  10. data/examples/rope_examples/itunes/lib/reports.rb +1 -0
  11. data/examples/rope_examples/itunes/lib/reports/playlist.rb +17 -0
  12. data/examples/rope_examples/itunes/log/ruport.log +1 -0
  13. data/examples/rope_examples/itunes/test/test_playlist.rb +8 -0
  14. data/examples/rope_examples/itunes/util/build +62 -0
  15. data/examples/rope_examples/itunes/util/sql_exec +5 -0
  16. data/examples/rope_examples/sales_report/README +4 -0
  17. data/examples/rope_examples/sales_report/Rakefile +18 -0
  18. data/examples/rope_examples/sales_report/config/ruport_config.rb +8 -0
  19. data/examples/rope_examples/sales_report/lib/helpers.rb +0 -0
  20. data/examples/rope_examples/sales_report/lib/init.rb +9 -0
  21. data/examples/rope_examples/sales_report/lib/reports.rb +1 -0
  22. data/examples/rope_examples/sales_report/lib/reports/sales.rb +138 -0
  23. data/examples/rope_examples/sales_report/log/ruport.log +1 -0
  24. data/examples/rope_examples/sales_report/output/books.pdf +170 -0
  25. data/examples/rope_examples/sales_report/output/books.txt +11 -0
  26. data/examples/rope_examples/sales_report/test/test_sales.rb +8 -0
  27. data/examples/rope_examples/sales_report/util/build +62 -0
  28. data/examples/rope_examples/sales_report/util/sql_exec +5 -0
  29. data/lib/ruport.rb +1 -1
  30. data/lib/ruport/data/groupable.rb +1 -1
  31. data/lib/ruport/data/record.rb +8 -8
  32. data/lib/ruport/data/table.rb +17 -14
  33. data/test/test_groupable.rb +14 -2
  34. data/test/test_table.rb +24 -0
  35. metadata +101 -60
  36. data/lib/ruport.rb.rej +0 -41
  37. data/lib/ruport.rb~ +0 -85
  38. data/lib/ruport/format/latex.rb.rej +0 -26
  39. data/lib/ruport/format/latex.rb~ +0 -47
  40. data/lib/ruport/format/pdf.rb.rej +0 -168
  41. data/lib/ruport/format/pdf.rb~ +0 -189
  42. data/test/unit.log +0 -259
data/lib/ruport.rb.rej DELETED
@@ -1,41 +0,0 @@
1
- ***************
2
- *** 9,20 ****
3
- #
4
- # See LICENSE and COPYING for details
5
- #
6
- -
7
- module Ruport
8
-
9
- VERSION = "0.7.2"
10
-
11
- - #
12
- # This method is Ruport's logging and error interface. It can generate
13
- # warnings or raise fatal errors, logging +message+ to the file defined by
14
- # <tt>Config::log_file</tt>.
15
- --- 9,18 ----
16
- #
17
- # See LICENSE and COPYING for details
18
- #
19
- module Ruport
20
-
21
- VERSION = "0.7.2"
22
-
23
- # This method is Ruport's logging and error interface. It can generate
24
- # warnings or raise fatal errors, logging +message+ to the file defined by
25
- # <tt>Config::log_file</tt>.
26
- ***************
27
- *** 54,60 ****
28
- # Alias for <tt>Ruport.log</tt>.
29
- def self.complain(*args); Ruport.log(*args) end
30
-
31
- - #
32
- # This method yields a <tt>Ruport::Config</tt> object, allowing you to
33
- # set the configuration options for your application.
34
- #
35
- --- 52,57 ----
36
- # Alias for <tt>Ruport.log</tt>.
37
- def self.complain(*args); Ruport.log(*args) end
38
-
39
- # This method yields a <tt>Ruport::Config</tt> object, allowing you to
40
- # set the configuration options for your application.
41
- #
data/lib/ruport.rb~ DELETED
@@ -1,85 +0,0 @@
1
- # ruport.rb : Ruby Reports top level module
2
- #
3
- # Author: Gregory T. Brown (gregory.t.brown at gmail dot com)
4
- #
5
- # Copyright (c) 2006, All Rights Reserved.
6
- #
7
- # This is free software. You may modify and redistribute this freely under
8
- # your choice of the GNU General Public License or the Ruby License.
9
- #
10
- # See LICENSE and COPYING for details
11
- #
12
-
13
- module Ruport
14
-
15
- VERSION = "0.7.99"
16
-
17
- #
18
- # This method is Ruport's logging and error interface. It can generate
19
- # warnings or raise fatal errors, logging +message+ to the file defined by
20
- # <tt>Config::log_file</tt>.
21
- #
22
- # You can configure the logging preferences with the +options+ hash.
23
- # Available options are:
24
- #
25
- # <b><tt>:status</tt></b>:: Sets the severity level. This defaults to
26
- # <tt>:warn</tt>, which will invoke
27
- # <tt>Logger#warn</tt>. A status of
28
- # <tt>:fatal</tt> will invoke
29
- # <tt>Logger#fatal</tt> and raise an exception.
30
- # <b><tt>:output</tt></b>:: Optional 2nd output. By default, <tt>log()</tt>
31
- # will print warnings to <tt>$stderr</tt> in
32
- # addition to <tt>Config::log_file</tt>. You
33
- # can redirect this to any I/O object with this
34
- # option.
35
- # <b><tt>:level</tt></b>:: Set this to <tt>:log_only</tt> to disable
36
- # secondary output. If you want to globally
37
- # override this setting for all calls to
38
- # <tt>log()</tt> (which can be useful for
39
- # debugging), you can set
40
- # <tt>Config.debug_mode</tt>.
41
- # <b><tt>:exception</tt></b>:: The +Exception+ to throw on failure. This
42
- # defaults to +RunTimeError+.
43
- #
44
- def self.log(message, options={})
45
- options = {:status => :warn, :output => $stderr}.merge(options)
46
- options[:output].puts "[!!] #{message}" unless
47
- options[:level].eql?(:log_only) and not Ruport::Config.debug_mode?
48
- Ruport::Config::logger.send(options[:status],message) if Config.logger
49
- if options[:status].eql? :fatal
50
- raise(options[:raises] || RuntimeError, message)
51
- end
52
- end
53
- #
54
- # This method yields a <tt>Ruport::Config</tt> object, allowing you to
55
- # set the configuration options for your application.
56
- #
57
- # Example:
58
- #
59
- # Ruport.configure do |c|
60
- #
61
- # c.source :default,
62
- # :dsn => "dbi:mysql:foo",
63
- # :user => "clyde",
64
- # :password => "pman"
65
- #
66
- # c.mailer :default,
67
- # :host => "mail.example.com",
68
- # :address => "inky@example.com"
69
- #
70
- # end
71
- #
72
- def self.configure(&block)
73
- block.call(Ruport::Config)
74
- end
75
- end
76
-
77
- require "ruport/attempt"
78
- require "ruport/config"
79
- require "ruport/data"
80
- require "ruport/report"
81
- require "ruport/format"
82
- require "ruport/query"
83
- require "ruport/mailer"
84
- require "ruport/layout"
85
- require "ruport/renderer"
@@ -1,26 +0,0 @@
1
- ***************
2
- *** 15,27 ****
3
- output << " }\n"
4
- output << "\\hline\n"
5
-
6
- - #FIXME: this ain't ruby, jh ;)
7
- - counter = 0
8
- -
9
- - data.column_names.each do |t|
10
- - output << " & " unless counter == 0
11
- output << "\\textsc{#{t}}"
12
- - counter += 1
13
- end
14
-
15
- output << "\\\\\n"
16
- --- 15,24 ----
17
- output << " }\n"
18
- output << "\\hline\n"
19
-
20
- + output << "\\textsc{#{data.column_names[0]}}"
21
- + data.column_names[1..-1].each do |t|
22
- + output << " & "
23
- output << "\\textsc{#{t}}"
24
- end
25
-
26
- output << "\\\\\n"
@@ -1,47 +0,0 @@
1
- module Ruport::Format
2
- class Latex < Plugin
3
-
4
- attr_accessor :caption
5
-
6
- def build_table_header
7
- output << "\\documentclass[11pt]{article}\n" <<
8
- "\\RequirePackage{lscape,longtable}\n" <<
9
- "\\begin{document}\n" <<
10
- "\\begin{longtable}[c]{ "
11
-
12
- data.column_names.each do
13
- output << " p{2cm} "
14
- end
15
- output << " }\n"
16
- output << "\\hline\n"
17
-
18
- output << "\\textsc{#{data.column_names[0]}}"
19
- data.column_names[1..-1].each do |t|
20
- output << " & "
21
- output << "\\textsc{#{t}}"
22
- end
23
-
24
- output << "\\\\\n"
25
- output << "\\hline\n"
26
- output << "\\endhead\n"
27
- output << "\\endfoot\n"
28
- output << "\\hline\n"
29
- end
30
-
31
- def build_table_body
32
- data.each do |r|
33
- output << r.to_a.join(" & ") + "\\\\\n"
34
- output << "\\hline\n"
35
- end
36
- if caption
37
- output << "\\caption[#{caption}]{#{caption}}\n"
38
- end
39
- output << "\\end{longtable}\n"
40
- end
41
-
42
- def build_table_footer
43
- output << "\\end{document}\n"
44
- end
45
-
46
- end
47
- end
@@ -1,168 +0,0 @@
1
- ***************
2
- *** 11,65 ****
3
- # * table_width
4
- # * max_table_width #=> 500
5
- #
6
- class PDF < Plugin
7
- attr_writer :pdf_writer
8
- attr_accessor :table_header_proc
9
- attr_accessor :table_footer_proc
10
-
11
- def initialize
12
- require "pdf/writer"
13
- require "pdf/simpletable"
14
- end
15
-
16
- def pdf_writer
17
- @pdf_writer ||=
18
- ::PDF::Writer.new( :paper => layout.paper_size || "LETTER" )
19
- end
20
-
21
- def build_table_header
22
- table_header_proc[pdf_writer] if table_header_proc
23
- end
24
-
25
- def build_table_body
26
- draw_table
27
- end
28
-
29
- def build_table_footer
30
- table_footer_proc[pdf_writer] if table_footer_proc
31
- end
32
-
33
- def finalize_table
34
- output << pdf_writer.render
35
- end
36
-
37
- def add_text(*args)
38
- pdf_writer.text(*args)
39
- end
40
-
41
- def move_cursor(n)
42
- pdf_writer.y += n
43
- end
44
-
45
- def move_cursor_to(n)
46
- pdf_writer.y = n
47
- end
48
-
49
- def pad(y,&block)
50
- move_cursor -y
51
- block.call
52
- move_cursor -y
53
- end
54
-
55
- def draw_table
56
- m = "Sorry, cant build PDFs from array like things (yet)"
57
- raise m if data.column_names.empty?
58
- --- 11,120 ----
59
- # * table_width
60
- # * max_table_width #=> 500
61
- #
62
- + # This class makes extensive use of Austin Zeigler's PDF::Writer
63
- + # Please refer to the API documentation for PDF::Writer if you need more
64
- + # information.
65
- + #
66
- class PDF < Plugin
67
- attr_writer :pdf_writer
68
- attr_accessor :table_header_proc
69
- attr_accessor :table_footer_proc
70
-
71
- + # Does the necessary PDF::Writer requires
72
- def initialize
73
- require "pdf/writer"
74
- require "pdf/simpletable"
75
- end
76
-
77
- + # Returns the current PDF::Writer object or creates a new one if it has not
78
- + # been set yet.
79
- + #
80
- def pdf_writer
81
- @pdf_writer ||=
82
- ::PDF::Writer.new( :paper => layout.paper_size || "LETTER" )
83
- end
84
-
85
- + # If table_header_proc is defined, it will be executed and the PDF::Writer
86
- + # object will be yielded.
87
- + #
88
- + # This should be overridden by subclasses, or used as a shortcut for your
89
- + # own plugin implementations
90
- + #
91
- + # This method is automatically called by the table renderer
92
- + #
93
- def build_table_header
94
- table_header_proc[pdf_writer] if table_header_proc
95
- end
96
-
97
- + # Calls the draw_table method
98
- + #
99
- + # This method is automatically called by the table renderer
100
- + #
101
- def build_table_body
102
- draw_table
103
- end
104
-
105
- + # If table_footer_proc is defined, it will be executed and the PDF::Writer
106
- + # object will be yielded.
107
- + #
108
- + # This should be overridden by subclasses, or used as a shortcut for your
109
- + # own plugin implementations
110
- + #
111
- + # This method is automatically called by the table renderer
112
- + #
113
- def build_table_footer
114
- table_footer_proc[pdf_writer] if table_footer_proc
115
- end
116
-
117
- + # Appends the results of PDF::Writer#render to output for your
118
- + # <tt>pdf_writer</tt> object.
119
- def finalize_table
120
- output << pdf_writer.render
121
- end
122
-
123
- + # Call PDF::Writer#text with the given arguments
124
- def add_text(*args)
125
- pdf_writer.text(*args)
126
- end
127
-
128
- + # Adds n to PDF::Writer#y.
129
- + #
130
- + # Basically, this allows you to move the rendering cursor up and down the page.
131
- + #
132
- + # move_cursor(10) #=> move up 10
133
- + # move_cursor(-10) #=> move down 10
134
- def move_cursor(n)
135
- pdf_writer.y += n
136
- end
137
-
138
- + # Sets PDF::Writer#y to n.
139
- + #
140
- + # This lets you move to a given height on the page.
141
- + #
142
- def move_cursor_to(n)
143
- pdf_writer.y = n
144
- end
145
-
146
- + # creates a margin of <tt>y</tt> amount and allows a block to be called to
147
- + # render items within that margin.
148
- + #
149
- + # Example:
150
- + #
151
- + # pad(10) { add_text 'hello' } #=> creates text hello with vertical margin
152
- + # of 10.
153
- def pad(y,&block)
154
- move_cursor -y
155
- block.call
156
- move_cursor -y
157
- end
158
-
159
- + # Builds a PDF::SimpleTable from a Data::Table
160
- + #
161
- + # Can be customized via the follow layout parameters:
162
- + #
163
- + # max_table_width #=> defaults to 500
164
- + # table_width #=> optionally set a fixed width for the table
165
- + # orientation #=> defaults to :center
166
- def draw_table
167
- m = "Sorry, cant build PDFs from array like things (yet)"
168
- raise m if data.column_names.empty?
@@ -1,189 +0,0 @@
1
- module Ruport::Format
2
-
3
- # PDF generation plugin
4
- #
5
- # layout options:
6
- # General:
7
- # * paper_size #=> "LETTER"
8
- # * orientation #=> :center
9
- #
10
- # Table:
11
- # * table_width
12
- # * max_table_width #=> 500
13
- #
14
- class PDF < Plugin
15
- attr_writer :pdf_writer
16
- attr_accessor :table_header_proc
17
- attr_accessor :table_footer_proc
18
-
19
- def initialize
20
- require "pdf/writer"
21
- require "pdf/simpletable"
22
- end
23
-
24
- def pdf_writer
25
- @pdf_writer ||=
26
- ::PDF::Writer.new( :paper => layout.paper_size || "LETTER" )
27
- end
28
-
29
- def build_table_header
30
- table_header_proc[pdf_writer] if table_header_proc
31
- end
32
-
33
- def build_table_body
34
- draw_table
35
- end
36
-
37
- def build_table_footer
38
- table_footer_proc[pdf_writer] if table_footer_proc
39
- end
40
-
41
- def finalize_table
42
- output << pdf_writer.render
43
- end
44
-
45
- def add_text(*args)
46
- pdf_writer.text(*args)
47
- end
48
-
49
- # - if the image is bigger than the box, it will be scaled down until it fits
50
- # - if the image is smaller than the box it's won't be resized
51
- #
52
- # arguments:
53
- # - x: left bound of box
54
- # - y: bottom bound of box
55
- # - width: width of box
56
- # - height: height of box
57
- def center_image_in_box(path, x, y, width, height)
58
- info = ::PDF::Writer::Graphics::ImageInfo.new(File.read(path))
59
-
60
- # if the image is larger than the requested box, prepare to
61
- # scale it down
62
- fits = !(info.width > width || info.height > height)
63
-
64
- # setup initial sizes for the image. These will be reduced as necesary
65
- img_width = info.width
66
- img_height = info.height
67
- img_ratio = info.height.to_f / info.width.to_f
68
-
69
- # reduce the size of the image until it fits into the requested box
70
- until fits
71
- img_width -= 1
72
- img_height = img_width * img_ratio
73
- fits = true if img_width < width && img_height < height
74
- end
75
-
76
- # if the width of the image is less than the requested box, calculate
77
- # the white space buffer
78
- if img_width < width
79
- white_space = width - img_width
80
- x = x + (white_space / 2)
81
- end
82
-
83
- # if the height of the image is less than the requested box, calculate
84
- # the white space buffer
85
- if img_height < height
86
- white_space = height - img_height
87
- y = y + (white_space / 2)
88
- end
89
-
90
- pdf_writer.add_image_from_file(path, x, y, img_width, img_height)
91
- end
92
-
93
- # Draws some text on the canvas, surrounded by a box with rounded corners
94
- #
95
- def rounded_text_box(text)
96
- opts = OpenStruct.new
97
- yield(opts)
98
-
99
- # resize the text automatically to ensure it isn't wider than the box
100
- loop do
101
- sz = pdf_writer.text_width( text, opts.font_size )
102
- opts.x + sz > opts.x + opts.width or break
103
- opts.font_size -= 1
104
- end
105
-
106
- # save the drawing state (colors, etc) so we can restore it later
107
- pdf_writer.save_state
108
-
109
- # draw our box
110
- pdf_writer.fill_color(opts.fill_color || Color::RGB::White)
111
- pdf_writer.stroke_color(opts.stroke_color || Color::RGB::Black)
112
- pdf_writer.rounded_rectangle( opts.x, opts.y,
113
- opts.width, opts.height,
114
- opts.radius).fill_stroke
115
-
116
- # if a heading for this box has been specified
117
- if opts.heading
118
- pdf_writer.line( opts.x, opts.y - 20,
119
- opts.x + opts.width, opts.y - 20).stroke
120
- pdf_writer.fill_color(Color::RGB::Black)
121
- move_cursor_to(opts.y - 3)
122
- add_text("<b>#{opts.heading}</b>",
123
- :absolute_left => opts.x, :absolute_right => opts.x + opts.width,
124
- :justification => :center, :font_size => opts.font_size)
125
- end
126
-
127
- # restore the original colors
128
- pdf_writer.restore_state
129
-
130
- # move our y cursor into position, write the text, then move the cursor
131
- # to be just below the box
132
- pdf_writer.y = opts.heading ? opts.y - 20 : opts.y
133
-
134
- add_text( text, :absolute_left => opts.x,
135
- :absolute_right => opts.x + opts.width,
136
- :justification => opts.justification || :center,
137
- :font_size => opts.font_size )
138
-
139
- pdf_writer.y = opts.y - opts.height
140
- end
141
-
142
- # adds an image to every page. The color and size won't be modified,
143
- # but it will be centered.
144
- #
145
- def watermark(imgpath)
146
- x = pdf_writer.absolute_left_margin
147
- y = pdf_writer.absolute_bottom_margin
148
- width = pdf_writer.absolute_right_margin - x
149
- height = pdf_writer.absolute_top_margin - y
150
-
151
- pdf_writer.open_object do |wm|
152
- pdf_writer.save_state
153
- center_image_in_box(imgpath, x, y, width, height)
154
- pdf_writer.restore_state
155
- pdf_writer.close_object
156
- pdf_writer.add_object(wm, :all_pages)
157
- end
158
- end
159
-
160
- def move_cursor(n)
161
- pdf_writer.y += n
162
- end
163
-
164
- def move_cursor_to(n)
165
- pdf_writer.y = n
166
- end
167
-
168
- def pad(y,&block)
169
- move_cursor -y
170
- block.call
171
- move_cursor -y
172
- end
173
-
174
- def draw_table
175
- m = "Sorry, cant build PDFs from array like things (yet)"
176
- raise m if data.column_names.empty?
177
- ::PDF::SimpleTable.new do |table|
178
- table.maximum_width = layout.max_table_width || 500
179
- table.width = layout.table_width if layout.table_width
180
- table.orientation = layout.orientation || :center
181
- table.data = data
182
- table.column_order = data.column_names
183
- table.render_on(pdf_writer)
184
- end
185
- end
186
-
187
-
188
- end
189
- end