libisi 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (91) hide show
  1. data/LICENSE +677 -0
  2. data/Manifest +89 -0
  3. data/Rakefile +34 -0
  4. data/lib/inifile.rb +119 -0
  5. data/lib/libisi.rb +948 -0
  6. data/lib/libisi/attribute.rb +32 -0
  7. data/lib/libisi/attribute/activerecord.rb +34 -0
  8. data/lib/libisi/attribute/base.rb +33 -0
  9. data/lib/libisi/base.rb +109 -0
  10. data/lib/libisi/bridge.rb +21 -0
  11. data/lib/libisi/bridge/base.rb +23 -0
  12. data/lib/libisi/bridge/java.rb +71 -0
  13. data/lib/libisi/bridge/python.rb +37 -0
  14. data/lib/libisi/cache.rb +21 -0
  15. data/lib/libisi/cache/base.rb +67 -0
  16. data/lib/libisi/cache/file_cache.rb +24 -0
  17. data/lib/libisi/chart.rb +21 -0
  18. data/lib/libisi/chart/base.rb +320 -0
  19. data/lib/libisi/chart/jfreechart.rb +682 -0
  20. data/lib/libisi/chart/jfreechart_generator.rb +206 -0
  21. data/lib/libisi/color.rb +21 -0
  22. data/lib/libisi/color/base.rb +66 -0
  23. data/lib/libisi/color/colortools.rb +92 -0
  24. data/lib/libisi/color/java.rb +44 -0
  25. data/lib/libisi/concept.rb +33 -0
  26. data/lib/libisi/concept/activerecord.rb +39 -0
  27. data/lib/libisi/concept/base.rb +58 -0
  28. data/lib/libisi/doc.rb +35 -0
  29. data/lib/libisi/doc/base.rb +414 -0
  30. data/lib/libisi/doc/html.rb +85 -0
  31. data/lib/libisi/doc/text.rb +98 -0
  32. data/lib/libisi/doc/wiki.rb +55 -0
  33. data/lib/libisi/environment.rb +21 -0
  34. data/lib/libisi/environment/base.rb +36 -0
  35. data/lib/libisi/environment/http.rb +105 -0
  36. data/lib/libisi/environment/rails.rb +27 -0
  37. data/lib/libisi/environment/root.rb +23 -0
  38. data/lib/libisi/fake_logger/logger.rb +61 -0
  39. data/lib/libisi/function/base.rb +30 -0
  40. data/lib/libisi/hal.rb +558 -0
  41. data/lib/libisi/instance.rb +27 -0
  42. data/lib/libisi/instance/activerecord.rb +21 -0
  43. data/lib/libisi/instance/base.rb +42 -0
  44. data/lib/libisi/log.rb +237 -0
  45. data/lib/libisi/mail/base.rb +32 -0
  46. data/lib/libisi/mail/tmail.rb +120 -0
  47. data/lib/libisi/parameter/base.rb +41 -0
  48. data/lib/libisi/property.rb +27 -0
  49. data/lib/libisi/property/base.rb +28 -0
  50. data/lib/libisi/reciever/base.rb +31 -0
  51. data/lib/libisi/reciever/socket.rb +31 -0
  52. data/lib/libisi/relation.rb +23 -0
  53. data/lib/libisi/request.rb +22 -0
  54. data/lib/libisi/request/base.rb +29 -0
  55. data/lib/libisi/request/http.rb +129 -0
  56. data/lib/libisi/response/base.rb +27 -0
  57. data/lib/libisi/task/base.rb +27 -0
  58. data/lib/libisi/task/http.rb +90 -0
  59. data/lib/libisi/tee.rb +296 -0
  60. data/lib/libisi/ui/base.rb +116 -0
  61. data/lib/libisi/ui/console.rb +238 -0
  62. data/lib/libisi/ui/kde.rb +94 -0
  63. data/lib/libisi/ui/nobody.rb +29 -0
  64. data/lib/libisi/ui/rails.rb +150 -0
  65. data/lib/libisi/ui/x11.rb +55 -0
  66. data/lib/libisi/uri.rb +42 -0
  67. data/lib/libisi/uri/activerecord.rb +152 -0
  68. data/lib/libisi/uri/base.rb +115 -0
  69. data/lib/libisi/uri/file.rb +43 -0
  70. data/lib/libisi/uri/ldap.rb +72 -0
  71. data/lib/libisi/uri/mysql.rb +98 -0
  72. data/lib/libisi/value.rb +31 -0
  73. data/lib/libisi/value/attribute_value.rb +19 -0
  74. data/lib/libisi/value/base.rb +55 -0
  75. data/lib/libisi/value/property_value.rb +19 -0
  76. data/lib/libisi/value/relation_value.rb +19 -0
  77. data/lib/ordered_hash.rb +228 -0
  78. data/libisi.gemspec +31 -0
  79. data/test/bridge_test.rb +77 -0
  80. data/test/cache_test.rb +65 -0
  81. data/test/chart_test.rb +179 -0
  82. data/test/color_test.rb +64 -0
  83. data/test/concept_test.rb +56 -0
  84. data/test/doc_test.rb +172 -0
  85. data/test/fixtures/test.db +0 -0
  86. data/test/ordered_hash_test.rb +39 -0
  87. data/test/profile_test.rb +36 -0
  88. data/test/request_test.rb +121 -0
  89. data/test/test +0 -0
  90. data/test/ui_test.rb +62 -0
  91. 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