libisi 0.3.0
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/LICENSE +677 -0
- data/Manifest +89 -0
- data/Rakefile +34 -0
- data/lib/inifile.rb +119 -0
- data/lib/libisi.rb +948 -0
- data/lib/libisi/attribute.rb +32 -0
- data/lib/libisi/attribute/activerecord.rb +34 -0
- data/lib/libisi/attribute/base.rb +33 -0
- data/lib/libisi/base.rb +109 -0
- data/lib/libisi/bridge.rb +21 -0
- data/lib/libisi/bridge/base.rb +23 -0
- data/lib/libisi/bridge/java.rb +71 -0
- data/lib/libisi/bridge/python.rb +37 -0
- data/lib/libisi/cache.rb +21 -0
- data/lib/libisi/cache/base.rb +67 -0
- data/lib/libisi/cache/file_cache.rb +24 -0
- data/lib/libisi/chart.rb +21 -0
- data/lib/libisi/chart/base.rb +320 -0
- data/lib/libisi/chart/jfreechart.rb +682 -0
- data/lib/libisi/chart/jfreechart_generator.rb +206 -0
- data/lib/libisi/color.rb +21 -0
- data/lib/libisi/color/base.rb +66 -0
- data/lib/libisi/color/colortools.rb +92 -0
- data/lib/libisi/color/java.rb +44 -0
- data/lib/libisi/concept.rb +33 -0
- data/lib/libisi/concept/activerecord.rb +39 -0
- data/lib/libisi/concept/base.rb +58 -0
- data/lib/libisi/doc.rb +35 -0
- data/lib/libisi/doc/base.rb +414 -0
- data/lib/libisi/doc/html.rb +85 -0
- data/lib/libisi/doc/text.rb +98 -0
- data/lib/libisi/doc/wiki.rb +55 -0
- data/lib/libisi/environment.rb +21 -0
- data/lib/libisi/environment/base.rb +36 -0
- data/lib/libisi/environment/http.rb +105 -0
- data/lib/libisi/environment/rails.rb +27 -0
- data/lib/libisi/environment/root.rb +23 -0
- data/lib/libisi/fake_logger/logger.rb +61 -0
- data/lib/libisi/function/base.rb +30 -0
- data/lib/libisi/hal.rb +558 -0
- data/lib/libisi/instance.rb +27 -0
- data/lib/libisi/instance/activerecord.rb +21 -0
- data/lib/libisi/instance/base.rb +42 -0
- data/lib/libisi/log.rb +237 -0
- data/lib/libisi/mail/base.rb +32 -0
- data/lib/libisi/mail/tmail.rb +120 -0
- data/lib/libisi/parameter/base.rb +41 -0
- data/lib/libisi/property.rb +27 -0
- data/lib/libisi/property/base.rb +28 -0
- data/lib/libisi/reciever/base.rb +31 -0
- data/lib/libisi/reciever/socket.rb +31 -0
- data/lib/libisi/relation.rb +23 -0
- data/lib/libisi/request.rb +22 -0
- data/lib/libisi/request/base.rb +29 -0
- data/lib/libisi/request/http.rb +129 -0
- data/lib/libisi/response/base.rb +27 -0
- data/lib/libisi/task/base.rb +27 -0
- data/lib/libisi/task/http.rb +90 -0
- data/lib/libisi/tee.rb +296 -0
- data/lib/libisi/ui/base.rb +116 -0
- data/lib/libisi/ui/console.rb +238 -0
- data/lib/libisi/ui/kde.rb +94 -0
- data/lib/libisi/ui/nobody.rb +29 -0
- data/lib/libisi/ui/rails.rb +150 -0
- data/lib/libisi/ui/x11.rb +55 -0
- data/lib/libisi/uri.rb +42 -0
- data/lib/libisi/uri/activerecord.rb +152 -0
- data/lib/libisi/uri/base.rb +115 -0
- data/lib/libisi/uri/file.rb +43 -0
- data/lib/libisi/uri/ldap.rb +72 -0
- data/lib/libisi/uri/mysql.rb +98 -0
- data/lib/libisi/value.rb +31 -0
- data/lib/libisi/value/attribute_value.rb +19 -0
- data/lib/libisi/value/base.rb +55 -0
- data/lib/libisi/value/property_value.rb +19 -0
- data/lib/libisi/value/relation_value.rb +19 -0
- data/lib/ordered_hash.rb +228 -0
- data/libisi.gemspec +31 -0
- data/test/bridge_test.rb +77 -0
- data/test/cache_test.rb +65 -0
- data/test/chart_test.rb +179 -0
- data/test/color_test.rb +64 -0
- data/test/concept_test.rb +56 -0
- data/test/doc_test.rb +172 -0
- data/test/fixtures/test.db +0 -0
- data/test/ordered_hash_test.rb +39 -0
- data/test/profile_test.rb +36 -0
- data/test/request_test.rb +121 -0
- data/test/test +0 -0
- data/test/ui_test.rb +62 -0
- metadata +244 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Copyright (C) 2007-2010 Logintas AG Switzerland
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Libisi.
|
|
4
|
+
#
|
|
5
|
+
# Libisi is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# Libisi is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Libisi. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require "libisi/base.rb"
|
|
19
|
+
require "libisi/instance/base.rb"
|
|
20
|
+
class Instance < Base
|
|
21
|
+
|
|
22
|
+
def self.create(object, options = {})
|
|
23
|
+
concept = Concept.create(object.class)
|
|
24
|
+
BaseInstance.new(concept, object, options)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# Copyright (C) 2007-2010 Logintas AG Switzerland
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Libisi.
|
|
4
|
+
#
|
|
5
|
+
# Libisi is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# Libisi is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Libisi. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
class ActiverecordInstance
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Copyright (C) 2007-2010 Logintas AG Switzerland
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Libisi.
|
|
4
|
+
#
|
|
5
|
+
# Libisi is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# Libisi is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Libisi. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require "libisi/value"
|
|
19
|
+
class BaseInstance
|
|
20
|
+
|
|
21
|
+
attr_reader :concept, :object
|
|
22
|
+
|
|
23
|
+
def initialize(concept, object, options = {})
|
|
24
|
+
@concept = concept
|
|
25
|
+
@object = object
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def value(name, options = {})
|
|
29
|
+
values.first {|v| v.name == name}
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def values(options = {})
|
|
33
|
+
|
|
34
|
+
if options[:type]
|
|
35
|
+
sources = concept.send(options[:type], options)
|
|
36
|
+
return sources.map {|a| Value.create(a, object)}
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
concept.value_accessors.map {|a| Value.create(a, object)}
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
end
|
data/lib/libisi/log.rb
ADDED
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# Copyright (C) 2007-2010 Logintas AG Switzerland
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Libisi.
|
|
4
|
+
#
|
|
5
|
+
# Libisi is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# Libisi is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Libisi. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require "libisi/base.rb"
|
|
19
|
+
require "log4r"
|
|
20
|
+
require 'log4r/configurator'
|
|
21
|
+
|
|
22
|
+
class Log < Base
|
|
23
|
+
LOG_FORMAT = "[%l] %d :: %m"
|
|
24
|
+
PRINT_DEBUG = false
|
|
25
|
+
|
|
26
|
+
def self.output_types
|
|
27
|
+
{"log" => ["err","error","debug","dbg","log"]}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.create_output(type, ending, file)
|
|
31
|
+
name = file.basename.to_s
|
|
32
|
+
case ending
|
|
33
|
+
when "err","error"
|
|
34
|
+
new_logger(name, file.to_s, :level => Logger::ERROR)
|
|
35
|
+
when "debug","dbg"
|
|
36
|
+
new_logger(name, file.to_s, :level => Logger::DEBUG)
|
|
37
|
+
when "log"
|
|
38
|
+
new_logger(name, file.to_s, :level => stdout_log_level)
|
|
39
|
+
else
|
|
40
|
+
raise "Unexpected ending #{ending}"
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def self.redefine_logger(options)
|
|
46
|
+
options[:redefine] ||= true
|
|
47
|
+
init(options)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def self.normalize_level(level)
|
|
51
|
+
level = level.to_s if level.class == Symbol
|
|
52
|
+
level = case level
|
|
53
|
+
when String, Symbol
|
|
54
|
+
Log4r.const_get(level.to_s.upcase)
|
|
55
|
+
when Fixnum
|
|
56
|
+
level
|
|
57
|
+
when NilClass
|
|
58
|
+
nil
|
|
59
|
+
else
|
|
60
|
+
raise "Unexpected log level class #{level.class} #{level.inspect}"
|
|
61
|
+
end
|
|
62
|
+
print "Normalized log level is #{level}\n" if PRINT_DEBUG
|
|
63
|
+
level
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def self.init(options = {})
|
|
67
|
+
#raise "Logging already initialized" if $log and !options[:redefine]
|
|
68
|
+
$log.debug("Redefine logger #{options.inspect}") if $log
|
|
69
|
+
|
|
70
|
+
# if defined?(RAILS_DEFAULT_LOGGER) and !options[:output]
|
|
71
|
+
# logfile = RAILS_DEFAULT_LOGGER.instance_eval("@log")
|
|
72
|
+
# raise "Cannot handle rails log destination #{logfile.class}" unless
|
|
73
|
+
# logfile.class == File
|
|
74
|
+
# RAILS_DEFAULT_LOGGER.info("Going to replace RAILS_DEFAULT_LOGGER by libisis own logger")
|
|
75
|
+
# options[:output] ||= logfile
|
|
76
|
+
# end
|
|
77
|
+
|
|
78
|
+
case options[:logging]
|
|
79
|
+
when nil, "Log4r", "log4r"
|
|
80
|
+
require "log4r"
|
|
81
|
+
|
|
82
|
+
# Initialize base logging
|
|
83
|
+
Log4r::Configurator.custom_levels(*options[:log_levels]) if options[:log_levels] and !options[:redefine]
|
|
84
|
+
# we need this to that log levels are initialized
|
|
85
|
+
Log4r::Logger.new("default")
|
|
86
|
+
|
|
87
|
+
options[:level] ||= (self.log_level_name or
|
|
88
|
+
(defined?(LOG_LEVEL) and LOG_LEVEL) or
|
|
89
|
+
ENV["LOG_LEVEL"] or "warn")
|
|
90
|
+
options[:level] = normalize_level(options[:level])
|
|
91
|
+
|
|
92
|
+
# new version: default_output = $environment.default_log_output
|
|
93
|
+
default_output = :stdout
|
|
94
|
+
options[:output] = nil if (options[:output].class == Array and options[:output].length == 0)
|
|
95
|
+
options[:output] ||= ((defined?(LOG_OUTPUT) and LOG_OUTPUT) or
|
|
96
|
+
ENV["LOG_OUTPUT"] or
|
|
97
|
+
default_output)
|
|
98
|
+
options[:output] = :stdout if options[:output] == "stdout"
|
|
99
|
+
options[:output] = [options[:output]] if options[:output].class != Array
|
|
100
|
+
|
|
101
|
+
$log.debug{"Create new logger now with Updated options: #{options.inspect}"} if $log
|
|
102
|
+
|
|
103
|
+
if !options[:redefine] or $log.nil? # new version: or $log.class == Libisi::Logging::FunctionCallLogger
|
|
104
|
+
$log = Log4r::Logger.new((ENV["PROGRAM_IDENT"] or "default"))
|
|
105
|
+
else
|
|
106
|
+
#$log.instance_variable_set("@outputters",[])
|
|
107
|
+
#$log.outputters.each {|o| $log.remove(o.name)}
|
|
108
|
+
$log.outputters = []
|
|
109
|
+
raise "Still outputters, maybe /usr/lib/ruby/1.8/logger.rb loaded" if $log.outputters.length != 0
|
|
110
|
+
@outputs = []
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
options[:output].each_with_index {|output, i|
|
|
114
|
+
new_logger("default#{i}", (output or :stdout), options)
|
|
115
|
+
}
|
|
116
|
+
else
|
|
117
|
+
raise "Unexpected logging mode #{options[:logging]}"
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
self.log_level = options[:level]
|
|
122
|
+
$log.debug("Logging initialized #{options.inspect}")
|
|
123
|
+
$log.outputters.each {|o| $log.debug("Outputter: #{o.inspect}") } if $log.debug?
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def self.outputs; @outputs or []; end
|
|
127
|
+
def self.new_logger(name, output, options = {})
|
|
128
|
+
raise "No outputter given." unless output
|
|
129
|
+
new_outputters = []
|
|
130
|
+
case output
|
|
131
|
+
when String, Pathname
|
|
132
|
+
new_outputters << Log4r::FileOutputter.new(name,:filename => output.to_s)
|
|
133
|
+
when :stdout
|
|
134
|
+
$stdout_logger||= Log4r::Outputter.stdout
|
|
135
|
+
$stderr_logger||= Log4r::Outputter.stderr
|
|
136
|
+
new_outputters << $stdout_logger
|
|
137
|
+
new_outputters << $stderr_logger
|
|
138
|
+
when :stderr
|
|
139
|
+
$stderr_logger||= Log4r::Outputter.stderr
|
|
140
|
+
new_outputters << $stderr_logger
|
|
141
|
+
when Hash
|
|
142
|
+
raise "unexpected output type #{output.inspect}"
|
|
143
|
+
else
|
|
144
|
+
new_outputters << Log4r::IOOutputter.new(name, output)
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
pattern = Log4r::PatternFormatter.new(:pattern => (options[:pattern] or LOG_FORMAT))
|
|
148
|
+
|
|
149
|
+
new_outputters.each_with_index {|out,i|
|
|
150
|
+
raise "Outputter #{i} is nil" unless out
|
|
151
|
+
old_len = $log.outputters.length
|
|
152
|
+
$log.add(out)
|
|
153
|
+
raise "No outputter added, maybe /usr/lib/ruby/1.8/logger.rb loaded" unless $log.outputters.length == (old_len + 1)
|
|
154
|
+
@outputs ||= []
|
|
155
|
+
@outputs << output
|
|
156
|
+
out.formatter = pattern
|
|
157
|
+
|
|
158
|
+
#normalize option
|
|
159
|
+
options[:only] = normalize_level(options[:only])
|
|
160
|
+
options[:level] = ((normalize_level(options[:level]) or $log.level))
|
|
161
|
+
|
|
162
|
+
# stderr level is always error
|
|
163
|
+
# and already defined
|
|
164
|
+
if output == :stdout
|
|
165
|
+
next if out == $stderr_logger
|
|
166
|
+
raise "Only log level not allowed for :stdout" if options[:only]
|
|
167
|
+
self.stdout_log_level = options[:level]
|
|
168
|
+
next
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
if options[:only]
|
|
172
|
+
out.only_at(options[:only])
|
|
173
|
+
$log.level = options[:only] if $log.level > options[:only]
|
|
174
|
+
end
|
|
175
|
+
if (options[:level])
|
|
176
|
+
out.level = options[:level]
|
|
177
|
+
$log.level = options[:level] if $log.level > options[:level]
|
|
178
|
+
end
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
print "Added new logger at #{output.inspect} (#{options.inspect})\n" if PRINT_DEBUG
|
|
182
|
+
$log.debug{"Added new logger at #{output.inspect} (#{options.inspect})"}
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
# LOGGING LEVELS
|
|
186
|
+
def self.log_level=(level)
|
|
187
|
+
$log.debug("Setting log_level #{level} (DEBUG is #{Log4r::DEBUG})")
|
|
188
|
+
|
|
189
|
+
$log.level = level
|
|
190
|
+
$log.outputters.each {|o|
|
|
191
|
+
next if o == $stdout_logger or o == $stderr_logger
|
|
192
|
+
o.level = level
|
|
193
|
+
}
|
|
194
|
+
self.stdout_log_level = level if $stdout_logger
|
|
195
|
+
@log_level = level
|
|
196
|
+
print "Log level is now #{$log.level} (set #{level})\n" if PRINT_DEBUG
|
|
197
|
+
$log.debug("Log level is now #{log_level_name}")
|
|
198
|
+
end
|
|
199
|
+
def self.log_level
|
|
200
|
+
@log_level ||= Log4r::WARN
|
|
201
|
+
@log_level
|
|
202
|
+
end
|
|
203
|
+
def self.log_level_name
|
|
204
|
+
return nil unless self.log_level
|
|
205
|
+
return nil unless defined?(Log4r::LNAMES)
|
|
206
|
+
Log4r::LNAMES[self.log_level]
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
def self.stdout_log_level
|
|
210
|
+
self.log_level
|
|
211
|
+
end
|
|
212
|
+
def self.stdout_log_level=(level)
|
|
213
|
+
return unless outputs.include?(:stdout)
|
|
214
|
+
print "set stdout level #{level} debug is: #{Log4r::DEBUG}\n" if PRINT_DEBUG
|
|
215
|
+
print "stdout_err_level: #{$stderr_logger.level}\n" if PRINT_DEBUG
|
|
216
|
+
print "stdout_log_level: #{$stdout_logger.level}\n" if PRINT_DEBUG
|
|
217
|
+
$stderr_logger.level = Log4r::ERROR
|
|
218
|
+
print "stderr_level: #{$stderr_logger.level}\n" if PRINT_DEBUG
|
|
219
|
+
|
|
220
|
+
raise "Level #{level} is too verbose" if level == 0
|
|
221
|
+
raise "Level #{level} is too quiet" if level >= Log4r::LEVELS - 2
|
|
222
|
+
if level >= (Log4r::LEVELS - 3)
|
|
223
|
+
$log.debug("Removing stdout logger")
|
|
224
|
+
$log.remove($stdout_logger.name)
|
|
225
|
+
print "removed stdout_logger\n" if PRINT_DEBUG
|
|
226
|
+
else
|
|
227
|
+
unless $log.outputters.include?($stdout_logger)
|
|
228
|
+
print "Added stdout_logger\n" if PRINT_DEBUG
|
|
229
|
+
$log.add($stdout_logger)
|
|
230
|
+
end
|
|
231
|
+
levels = (level..Log4r::LEVELS-4).to_a
|
|
232
|
+
print "Stdout levels: #{levels.inspect}\n" if PRINT_DEBUG
|
|
233
|
+
$stdout_logger.only_at(*levels)
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Copyright (C) 2007-2010 Logintas AG Switzerland
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Libisi.
|
|
4
|
+
#
|
|
5
|
+
# Libisi is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# Libisi is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Libisi. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
class BaseMail
|
|
19
|
+
|
|
20
|
+
def default_from
|
|
21
|
+
"#{program_name.inspect} <#{user}@#{full_qualified_domainname}>"
|
|
22
|
+
end
|
|
23
|
+
def default_subject
|
|
24
|
+
"Email from #{program_name.inspect} on #{full_qualified_domainname} by #{user}"
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def send_email(recipients, text, options = {}); send_mail(recipients, text, options); end
|
|
28
|
+
def send_mail(recipients, text, options = {})
|
|
29
|
+
raise "not implemented"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
end
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
# Copyright (C) 2007-2010 Logintas AG Switzerland
|
|
2
|
+
#
|
|
3
|
+
# This file is part of Libisi.
|
|
4
|
+
#
|
|
5
|
+
# Libisi is free software: you can redistribute it and/or modify
|
|
6
|
+
# it under the terms of the GNU General Public License as published by
|
|
7
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
8
|
+
# (at your option) any later version.
|
|
9
|
+
#
|
|
10
|
+
# Libisi is distributed in the hope that it will be useful,
|
|
11
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
13
|
+
# GNU General Public License for more details.
|
|
14
|
+
#
|
|
15
|
+
# You should have received a copy of the GNU General Public License
|
|
16
|
+
# along with Libisi. If not, see <http://www.gnu.org/licenses/>.
|
|
17
|
+
|
|
18
|
+
require 'tmail'
|
|
19
|
+
require 'libisi/mail/base'
|
|
20
|
+
require 'net/smtp'
|
|
21
|
+
require 'base64'
|
|
22
|
+
|
|
23
|
+
# bugfix
|
|
24
|
+
module TMail
|
|
25
|
+
module TextUtils
|
|
26
|
+
private
|
|
27
|
+
def random_tag
|
|
28
|
+
@@uniq += 1
|
|
29
|
+
t = Time.now
|
|
30
|
+
sprintf('%x%x_%x%x%d%x',
|
|
31
|
+
t.to_i, t.tv_usec,
|
|
32
|
+
$$, Thread.current.object_id, @@uniq, rand(255))
|
|
33
|
+
# was
|
|
34
|
+
# $$, Thread.current.id, @@uniq, rand(255))
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TMailMail < BaseMail
|
|
41
|
+
|
|
42
|
+
def send_mail(recipients, text, options = {})
|
|
43
|
+
mail = TMail::Mail.new()
|
|
44
|
+
mail.date = Time.now
|
|
45
|
+
mail.to = recipients
|
|
46
|
+
mail.from = (options[:from] or self.default_from)
|
|
47
|
+
mail.subject = (options[:subject] or self.default_subject)
|
|
48
|
+
if (ccs = options[:cc])
|
|
49
|
+
$log.debug("Sending mail cc to #{ccs.inspect}")
|
|
50
|
+
mail.cc = ccs
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if (bccs = options[:bcc])
|
|
54
|
+
$log.debug("Sending mail bcc to #{bccs.inspect}")
|
|
55
|
+
mail.bcc = bccs
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
mail.mime_version = "1.0"
|
|
59
|
+
|
|
60
|
+
text = text.readlines.join("\n") if text.respond_to?(:readlines)
|
|
61
|
+
if text =~ /\<html/
|
|
62
|
+
# for html
|
|
63
|
+
$log.debug("Expecting text has content type html")
|
|
64
|
+
mail.parts.push(create_text_part(text, "html"))
|
|
65
|
+
else
|
|
66
|
+
$log.debug("Expecting text has content type text")
|
|
67
|
+
mail.parts.push(create_text_part(text))
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
(options[:attachments] or []).each {|a|
|
|
71
|
+
mail.parts.push(create_attachment(a))
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# this have to be after parts has been added, otherwisse
|
|
75
|
+
# "can't convert nil into String" will be thrown on adding parts
|
|
76
|
+
mail.set_content_type( 'multipart', 'mixed' )
|
|
77
|
+
mail.message_id = TMail.new_message_id(full_qualified_domainname)
|
|
78
|
+
|
|
79
|
+
Net::SMTP.start("localhost",25) do |smtpclient|
|
|
80
|
+
$log.info("Sending mail with subject #{mail.subject.to_s.inspect} to #{mail.to.to_s.inspect}")
|
|
81
|
+
smtpclient.send_message(mail.to_s, mail.from, mail.to)
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def create_text_part(text, content_type = "plain")
|
|
86
|
+
text_part = TMail::Mail.new
|
|
87
|
+
text_part.body = text
|
|
88
|
+
text_part.charset = 'utf-8'
|
|
89
|
+
text_part.transfer_encoding = '7bit'
|
|
90
|
+
text_part.set_content_type('text', content_type)
|
|
91
|
+
text_part
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def create_attachment(file_name)
|
|
95
|
+
file = Pathname.new(file_name)
|
|
96
|
+
raise "File not readable: #{file_name}" unless file.readable?
|
|
97
|
+
$log.info("Creating attachment #{file_name}")
|
|
98
|
+
attachment = TMail::Mail.new
|
|
99
|
+
if file_name =~ /bz2/ or file_name =~ /bzip2/
|
|
100
|
+
attachment.body = Base64.encode64(Pathname.new(file_name).readlines.join)
|
|
101
|
+
file_name = file.basename
|
|
102
|
+
else
|
|
103
|
+
$log.info("Compressing attachment to bz2")
|
|
104
|
+
command = "|cat #{file_name.to_s.inspect} | bzip2"
|
|
105
|
+
$log.debug{"Compression command is: #{command.inspect}"}
|
|
106
|
+
compr = open(command) {|f| f.readlines.join}
|
|
107
|
+
raise "Error compressing attachment." unless $?.success?
|
|
108
|
+
$log.info("Compressed file has length #{compr.length}")
|
|
109
|
+
attachment.body = Base64.encode64(compr)
|
|
110
|
+
file_name = "#{file.basename}.bz2"
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
$log.debug("Attaching file #{file_name}")
|
|
114
|
+
attachment.transfer_encoding = '7bit'
|
|
115
|
+
attachment.encoding = 'base64'
|
|
116
|
+
attachment.set_content_type('application', 'x-bzip', 'name' => "#{file_name.to_s}")
|
|
117
|
+
attachment.header["Content-Disposition"] = "attachment; filename=#{file_name.to_s}"
|
|
118
|
+
attachment
|
|
119
|
+
end
|
|
120
|
+
end
|