ruport 0.7.1 → 0.7.2
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/AUTHORS +4 -2
- data/README +4 -3
- data/Rakefile +1 -1
- data/lib/ruport.rb +1 -4
- data/lib/ruport/config.rb +6 -11
- data/lib/ruport/data/collection.rb +8 -2
- data/lib/ruport/data/groupable.rb +0 -2
- data/lib/ruport/data/record.rb +0 -13
- data/lib/ruport/data/set.rb +0 -8
- data/lib/ruport/data/table.rb +1 -18
- data/lib/ruport/data/taggable.rb +1 -6
- data/lib/ruport/format/latex.rb +5 -8
- data/lib/ruport/format/pdf.rb +56 -0
- data/lib/ruport/format/plugin.rb +5 -0
- data/lib/ruport/format/svg.rb +26 -4
- data/lib/ruport/format/text.rb +25 -2
- data/lib/ruport/format/xml.rb +1 -1
- data/lib/ruport/generator.rb +1 -1
- data/lib/ruport/mailer.rb +1 -4
- data/lib/ruport/query.rb +0 -9
- data/lib/ruport/renderer.rb +15 -1
- data/lib/ruport/report.rb +5 -22
- data/test/test_mailer.rb +86 -24
- data/test/test_report.rb +72 -1
- data/test/test_table.rb +15 -0
- data/test/unit.log +7 -277
- metadata +34 -44
- data/lib/ruport.rb~ +0 -69
- data/lib/ruport/data.rb.rej +0 -5
- data/lib/ruport/data.rb~ +0 -1
- data/lib/ruport/data/record.rb~ +0 -236
- data/lib/ruport/data/table.rb.rej +0 -67
- data/lib/ruport/data/table.rb~ +0 -414
- data/test/test_query.rb.rej +0 -161
- data/test/test_query.rb~ +0 -337
- data/test/test_record.rb.rej +0 -46
- data/test/test_table.rb~ +0 -336
data/lib/ruport/data/taggable.rb
CHANGED
@@ -5,7 +5,7 @@
|
|
5
5
|
# Copyright 2006 by respective content owners, all rights reserved.
|
6
6
|
module Ruport::Data
|
7
7
|
|
8
|
-
|
8
|
+
|
9
9
|
# === Overview
|
10
10
|
#
|
11
11
|
# This module provides a simple mechanism for tagging arbitrary objects.
|
@@ -14,7 +14,6 @@ module Ruport::Data
|
|
14
14
|
#
|
15
15
|
module Taggable
|
16
16
|
|
17
|
-
#
|
18
17
|
# Adds a tag to the object.
|
19
18
|
#
|
20
19
|
# Example:
|
@@ -25,7 +24,6 @@ module Ruport::Data
|
|
25
24
|
tags << tag_name unless has_tag? tag_name
|
26
25
|
end
|
27
26
|
|
28
|
-
#
|
29
27
|
# Removes a tag from the object.
|
30
28
|
#
|
31
29
|
# Example:
|
@@ -36,7 +34,6 @@ module Ruport::Data
|
|
36
34
|
tags.delete tag_name
|
37
35
|
end
|
38
36
|
|
39
|
-
#
|
40
37
|
# Checks to see if a tag is present.
|
41
38
|
#
|
42
39
|
# Example:
|
@@ -47,7 +44,6 @@ module Ruport::Data
|
|
47
44
|
tags.include? tag_name
|
48
45
|
end
|
49
46
|
|
50
|
-
#
|
51
47
|
# Returns an Array of the object's tags.
|
52
48
|
#
|
53
49
|
# Example:
|
@@ -58,7 +54,6 @@ module Ruport::Data
|
|
58
54
|
@ruport_tags ||= []
|
59
55
|
end
|
60
56
|
|
61
|
-
#
|
62
57
|
# Sets the tags to some Array.
|
63
58
|
#
|
64
59
|
# Example:
|
data/lib/ruport/format/latex.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Ruport::Format
|
2
|
-
class Latex < Plugin
|
2
|
+
class Latex < Plugin #:nodoc:
|
3
3
|
|
4
4
|
attr_accessor :caption
|
5
|
-
|
5
|
+
|
6
6
|
def build_table_header
|
7
7
|
output << "\\documentclass[11pt]{article}\n" <<
|
8
8
|
"\\RequirePackage{lscape,longtable}\n" <<
|
@@ -15,13 +15,10 @@ module Ruport::Format
|
|
15
15
|
output << " }\n"
|
16
16
|
output << "\\hline\n"
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
data.column_names.each do |t|
|
22
|
-
output << " & " unless counter == 0
|
18
|
+
output << "\\textsc{#{data.column_names[0]}}"
|
19
|
+
data.column_names[1..-1].each do |t|
|
20
|
+
output << " & "
|
23
21
|
output << "\\textsc{#{t}}"
|
24
|
-
counter += 1
|
25
22
|
end
|
26
23
|
|
27
24
|
output << "\\\\\n"
|
data/lib/ruport/format/pdf.rb
CHANGED
@@ -11,55 +11,111 @@ module Ruport::Format
|
|
11
11
|
# * table_width
|
12
12
|
# * max_table_width #=> 500
|
13
13
|
#
|
14
|
+
# This class makes extensive use of Austin Zeigler's PDF::Writer
|
15
|
+
# Please refer to the API documentation for PDF::Writer if you need more
|
16
|
+
# information.
|
17
|
+
#
|
14
18
|
class PDF < Plugin
|
15
19
|
attr_writer :pdf_writer
|
16
20
|
attr_accessor :table_header_proc
|
17
21
|
attr_accessor :table_footer_proc
|
18
22
|
|
23
|
+
# Does the necessary PDF::Writer requires
|
19
24
|
def initialize
|
20
25
|
require "pdf/writer"
|
21
26
|
require "pdf/simpletable"
|
22
27
|
end
|
23
28
|
|
29
|
+
# Returns the current PDF::Writer object or creates a new one if it has not
|
30
|
+
# been set yet.
|
31
|
+
#
|
24
32
|
def pdf_writer
|
25
33
|
@pdf_writer ||=
|
26
34
|
::PDF::Writer.new( :paper => layout.paper_size || "LETTER" )
|
27
35
|
end
|
28
36
|
|
37
|
+
# If table_header_proc is defined, it will be executed and the PDF::Writer
|
38
|
+
# object will be yielded.
|
39
|
+
#
|
40
|
+
# This should be overridden by subclasses, or used as a shortcut for your
|
41
|
+
# own plugin implementations
|
42
|
+
#
|
43
|
+
# This method is automatically called by the table renderer
|
44
|
+
#
|
29
45
|
def build_table_header
|
30
46
|
table_header_proc[pdf_writer] if table_header_proc
|
31
47
|
end
|
32
48
|
|
49
|
+
# Calls the draw_table method
|
50
|
+
#
|
51
|
+
# This method is automatically called by the table renderer
|
52
|
+
#
|
33
53
|
def build_table_body
|
34
54
|
draw_table
|
35
55
|
end
|
36
56
|
|
57
|
+
# If table_footer_proc is defined, it will be executed and the PDF::Writer
|
58
|
+
# object will be yielded.
|
59
|
+
#
|
60
|
+
# This should be overridden by subclasses, or used as a shortcut for your
|
61
|
+
# own plugin implementations
|
62
|
+
#
|
63
|
+
# This method is automatically called by the table renderer
|
64
|
+
#
|
37
65
|
def build_table_footer
|
38
66
|
table_footer_proc[pdf_writer] if table_footer_proc
|
39
67
|
end
|
40
68
|
|
69
|
+
# Appends the results of PDF::Writer#render to output for your
|
70
|
+
# <tt>pdf_writer</tt> object.
|
71
|
+
#
|
41
72
|
def finalize_table
|
42
73
|
output << pdf_writer.render
|
43
74
|
end
|
44
75
|
|
76
|
+
# Call PDF::Writer#text with the given arguments
|
45
77
|
def add_text(*args)
|
46
78
|
pdf_writer.text(*args)
|
47
79
|
end
|
48
80
|
|
81
|
+
# Adds n to PDF::Writer#y.
|
82
|
+
#
|
83
|
+
# Basically, this allows you to move the rendering cursor up and down the page.
|
84
|
+
#
|
85
|
+
# move_cursor(10) #=> move up 10
|
86
|
+
# move_cursor(-10) #=> move down 10
|
49
87
|
def move_cursor(n)
|
50
88
|
pdf_writer.y += n
|
51
89
|
end
|
52
90
|
|
91
|
+
# Sets PDF::Writer#y to n.
|
92
|
+
#
|
93
|
+
# This lets you move to a given height on the page.
|
94
|
+
#
|
53
95
|
def move_cursor_to(n)
|
54
96
|
pdf_writer.y = n
|
55
97
|
end
|
56
98
|
|
99
|
+
# creates a margin of <tt>y</tt> amount and allows a block to be called to
|
100
|
+
# render items within that margin.
|
101
|
+
#
|
102
|
+
# Example:
|
103
|
+
#
|
104
|
+
# pad(10) { add_text 'hello' } #=> creates text hello with vertical margin
|
105
|
+
# of 10.
|
57
106
|
def pad(y,&block)
|
58
107
|
move_cursor -y
|
59
108
|
block.call
|
60
109
|
move_cursor -y
|
61
110
|
end
|
62
111
|
|
112
|
+
# Builds a PDF::SimpleTable from a Data::Table
|
113
|
+
#
|
114
|
+
# Can be customized via the follow layout parameters:
|
115
|
+
#
|
116
|
+
# max_table_width #=> defaults to 500
|
117
|
+
# table_width #=> optionally set a fixed width for the table
|
118
|
+
# orientation #=> defaults to :center
|
63
119
|
def draw_table
|
64
120
|
m = "Sorry, cant build PDFs from array like things (yet)"
|
65
121
|
raise m if data.column_names.empty?
|
data/lib/ruport/format/plugin.rb
CHANGED
@@ -8,7 +8,10 @@ module Ruport
|
|
8
8
|
module Format
|
9
9
|
class Plugin
|
10
10
|
|
11
|
+
# Shared with renderer
|
11
12
|
attr_accessor :layout
|
13
|
+
|
14
|
+
# Shared with renderer
|
12
15
|
attr_accessor :data
|
13
16
|
|
14
17
|
# Stores a string used for outputting formatted data.
|
@@ -17,6 +20,8 @@ module Ruport
|
|
17
20
|
end
|
18
21
|
|
19
22
|
# Provides a generic OpenStruct for storing plugin options
|
23
|
+
#
|
24
|
+
# This is shared with the renderer object
|
20
25
|
def options
|
21
26
|
@options ||= OpenStruct.new
|
22
27
|
end
|
data/lib/ruport/format/svg.rb
CHANGED
@@ -1,28 +1,44 @@
|
|
1
1
|
module Ruport::Format
|
2
2
|
class SVG < Plugin
|
3
|
-
|
4
|
-
|
3
|
+
|
4
|
+
# a hash of Scruffy themes.
|
5
|
+
#
|
6
|
+
# You can use these by setting layout.theme like this:
|
7
|
+
#
|
8
|
+
# Graph.render_svg { |r| r.layout.theme = r.plugin.themes[:mephisto] }
|
9
|
+
#
|
10
|
+
# Available themes: ( :mephisto, :keynote, :ruby_blog )
|
11
|
+
#
|
5
12
|
def themes
|
6
13
|
{ :mephisto => Scruffy::Themes::Mephisto.new,
|
7
14
|
:keynote => Scruffy::Themes::Keynote.new,
|
8
15
|
:ruby_blog => Scruffy::Themes::RubyBlog.new }
|
9
16
|
end
|
10
17
|
|
18
|
+
# generates a scruffy graph object
|
11
19
|
def initialize
|
12
20
|
require 'scruffy'
|
13
21
|
|
14
22
|
@graph = Scruffy::Graph.new
|
15
23
|
end
|
16
24
|
|
25
|
+
# the Scruffy::Graph object
|
17
26
|
attr_reader :graph
|
18
27
|
|
28
|
+
# sets the graph title, theme, and column_names
|
29
|
+
#
|
30
|
+
# column_names are defined by the Data::Table,
|
31
|
+
# theme may be specified by layout.theme (see SVG#themes)
|
32
|
+
# title may be specified by options.title
|
33
|
+
#
|
19
34
|
def prepare_graph
|
20
35
|
@graph.title ||= options.title
|
21
36
|
@graph.theme = layout.theme if layout.theme
|
22
37
|
@graph.point_markers ||= data.column_names
|
23
|
-
|
24
38
|
end
|
25
39
|
|
40
|
+
|
41
|
+
# Generates an SVG using Scruffy.
|
26
42
|
def build_graph
|
27
43
|
data.each_with_index do |r,i|
|
28
44
|
add_line(r.data,r.tags[0] || "series #{i+1}")
|
@@ -30,7 +46,13 @@ module Ruport::Format
|
|
30
46
|
|
31
47
|
output << @graph.render(:size => [layout.width, layout.height])
|
32
48
|
end
|
33
|
-
|
49
|
+
|
50
|
+
# Uses Scruffy::Graph#add to add a new line to the graph.
|
51
|
+
#
|
52
|
+
# Will use the first tag on a Record as the label if present.
|
53
|
+
#
|
54
|
+
# Line style is determined by layout.style
|
55
|
+
#
|
34
56
|
def add_line(row,label)
|
35
57
|
@graph.add( layout.style, label, row )
|
36
58
|
end
|
data/lib/ruport/format/text.rb
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
module Ruport
|
2
2
|
module Format
|
3
3
|
class Text < Plugin
|
4
|
-
|
4
|
+
|
5
|
+
# Checks to ensure the table is not empty and then calls
|
6
|
+
# calculate_max_col_widths
|
7
|
+
#
|
5
8
|
def prepare_table
|
6
9
|
raise "Can't output empty table" if data.empty?
|
7
10
|
calculate_max_col_widths
|
8
11
|
end
|
9
12
|
|
13
|
+
# Uses the column names from the given Data::Table to generate a table
|
14
|
+
# header.
|
15
|
+
#
|
16
|
+
# calls fit_to_width to truncate table heading if necessary.
|
10
17
|
def build_table_header
|
11
18
|
return if data.column_names.empty? || !layout.show_table_headers
|
12
19
|
c = data.column_names.dup
|
@@ -16,6 +23,13 @@ module Ruport
|
|
16
23
|
output << fit_to_width("#{hr}| #{c.to_a.join(' | ')} |\n")
|
17
24
|
end
|
18
25
|
|
26
|
+
# Generates the body of the text table.
|
27
|
+
#
|
28
|
+
# Defaults to numeric values being right justified, and other values being
|
29
|
+
# left justified. Can be changed to support centering of output by
|
30
|
+
# setting layout.alignment to :center
|
31
|
+
#
|
32
|
+
# Uses fit_to_width to truncate table if necessary
|
19
33
|
def build_table_body
|
20
34
|
s = hr
|
21
35
|
|
@@ -36,22 +50,31 @@ module Ruport
|
|
36
50
|
output << fit_to_width(s)
|
37
51
|
end
|
38
52
|
|
53
|
+
# Generates the horizontal rule by calculating the total table width and
|
54
|
+
# then generating a bar that looks like this:
|
55
|
+
#
|
56
|
+
# "+------------------+"
|
39
57
|
def hr
|
40
58
|
len = layout.max_col_width.inject(data[0].to_a.length * 3) {|s,e|s+e}+1
|
41
59
|
"+" + "-"*(len-2) + "+\n"
|
42
60
|
end
|
43
|
-
|
61
|
+
|
62
|
+
# Returns layout.table_width if specified.
|
63
|
+
#
|
64
|
+
# Otherwise, uses SystemExtensions to determine terminal width.
|
44
65
|
def width
|
45
66
|
require "ruport/system_extensions"
|
46
67
|
layout.table_width || SystemExtensions.terminal_width
|
47
68
|
end
|
48
69
|
|
70
|
+
# Truncates a string so that it does not exceed Text#width
|
49
71
|
def fit_to_width(s)
|
50
72
|
s.split("\n").each { |r|
|
51
73
|
r.gsub!(/\A.{#{width+1},}/) { |m| m[0,width-2] + ">>" }
|
52
74
|
}.join("\n") + "\n"
|
53
75
|
end
|
54
76
|
|
77
|
+
# determines the text widths for each column.
|
55
78
|
def calculate_max_col_widths
|
56
79
|
# allow override
|
57
80
|
return if layout.max_col_width
|
data/lib/ruport/format/xml.rb
CHANGED
data/lib/ruport/generator.rb
CHANGED
data/lib/ruport/mailer.rb
CHANGED
@@ -9,7 +9,6 @@ require "forwardable"
|
|
9
9
|
|
10
10
|
module Ruport
|
11
11
|
|
12
|
-
#
|
13
12
|
# === Overview
|
14
13
|
#
|
15
14
|
# This class uses SMTP to provide a simple mail sending mechanism.
|
@@ -39,7 +38,6 @@ module Ruport
|
|
39
38
|
class Mailer
|
40
39
|
extend Forwardable
|
41
40
|
|
42
|
-
#
|
43
41
|
# Creates a new Mailer object. Optionally, you can select a mailer
|
44
42
|
# specified by Ruport::Config.
|
45
43
|
#
|
@@ -58,8 +56,7 @@ module Ruport
|
|
58
56
|
def_delegators( :@mail, :to, :to=, :from, :from=,
|
59
57
|
:subject, :subject=, :attach,
|
60
58
|
:text, :text=, :html, :html= )
|
61
|
-
|
62
|
-
#
|
59
|
+
|
63
60
|
# Sends the message.
|
64
61
|
#
|
65
62
|
# Example:
|
data/lib/ruport/query.rb
CHANGED
@@ -3,7 +3,6 @@ require "ruport/query/sql_split"
|
|
3
3
|
|
4
4
|
module Ruport
|
5
5
|
|
6
|
-
#
|
7
6
|
# === Overview
|
8
7
|
#
|
9
8
|
# Query offers a way to interact with databases via DBI. It supports
|
@@ -19,7 +18,6 @@ module Ruport
|
|
19
18
|
|
20
19
|
include Enumerable
|
21
20
|
|
22
|
-
#
|
23
21
|
# Queries are initialized with some SQL and a number of options that
|
24
22
|
# affect their operation. They are NOT executed at initialization. This
|
25
23
|
# is important to note as they will not query the database until either
|
@@ -98,7 +96,6 @@ module Ruport
|
|
98
96
|
@cached_data = nil
|
99
97
|
end
|
100
98
|
|
101
|
-
#
|
102
99
|
# Set this to <tt>true</tt> to get DBI:Rows, <tt>false</tt> to get Ruport
|
103
100
|
# constructs.
|
104
101
|
#
|
@@ -110,7 +107,6 @@ module Ruport
|
|
110
107
|
# The original SQL for the Query object
|
111
108
|
attr_reader :sql
|
112
109
|
|
113
|
-
#
|
114
110
|
# This will set the <tt>dsn</tt>, <tt>username</tt>, and <tt>password</tt>
|
115
111
|
# to one specified by a source in Ruport::Config.
|
116
112
|
#
|
@@ -120,7 +116,6 @@ module Ruport
|
|
120
116
|
@password = Ruport::Config.sources[label].password
|
121
117
|
end
|
122
118
|
|
123
|
-
#
|
124
119
|
# Standard <tt>each</tt> iterator, iterates through the result set row by
|
125
120
|
# row.
|
126
121
|
#
|
@@ -133,7 +128,6 @@ module Ruport
|
|
133
128
|
self
|
134
129
|
end
|
135
130
|
|
136
|
-
#
|
137
131
|
# Grabs the result set as a Data::Table or an Array of DBI::Row objects
|
138
132
|
# if in <tt>raw_data</tt> mode.
|
139
133
|
#
|
@@ -147,7 +141,6 @@ module Ruport
|
|
147
141
|
@cached_data = nil
|
148
142
|
end
|
149
143
|
|
150
|
-
#
|
151
144
|
# Clears the contents of the cache, then runs the query, filling the
|
152
145
|
# cache with the new result.
|
153
146
|
#
|
@@ -156,7 +149,6 @@ module Ruport
|
|
156
149
|
clear_cache; fetch
|
157
150
|
end
|
158
151
|
|
159
|
-
#
|
160
152
|
# Turns on caching. New data will not be loaded until the cache is clear
|
161
153
|
# or caching is disabled.
|
162
154
|
#
|
@@ -170,7 +162,6 @@ module Ruport
|
|
170
162
|
@cache_enabled = false
|
171
163
|
end
|
172
164
|
|
173
|
-
#
|
174
165
|
# Returns a Data::Table, even if in <tt>raw_data</tt> mode.
|
175
166
|
# This doesn't work with raw data if the cache is enabled and filled.
|
176
167
|
#
|