ruport 0.7.1 → 0.7.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
#
|