cremefraiche 1.1.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of cremefraiche might be problematic. Click here for more details.
- checksums.yaml +7 -0
- data/bin/cremefraiche +25 -0
- data/bin/cremefraicheGui +26 -0
- data/cremefraiche.gemspec +24 -0
- data/lib/LANG +1 -0
- data/lib/busy_indicator/busy_function_test.rb +56 -0
- data/lib/busy_indicator/busy_indicator.rb +95 -0
- data/lib/busy_indicator/color_output.rb +51 -0
- data/lib/cfprawn.rb +394 -0
- data/lib/confcheck.rb +112 -0
- data/lib/config +192 -0
- data/lib/configuration.rb +259 -0
- data/lib/cremefraiche.rb +341 -0
- data/lib/emlfile.rb +140 -0
- data/lib/file_checking.rb +87 -0
- data/lib/gui/AboutDialog.rb +64 -0
- data/lib/gui/ButtonLabel.rb +49 -0
- data/lib/gui/ConfDialog.rb +618 -0
- data/lib/gui/HowtoDialog.rb +184 -0
- data/lib/gui/conf_option.rb +279 -0
- data/lib/gui/conf_value.rb +65 -0
- data/lib/gui/cremefraicheGui.rb +625 -0
- data/lib/gui/gtk-about.xpm +90 -0
- data/lib/gui/gtk-close.xpm +90 -0
- data/lib/gui/gtk-execute.xpm +118 -0
- data/lib/gui/gtk-open.xpm +147 -0
- data/lib/gui/gtk-properties.xpm +378 -0
- data/lib/gui/gtk-quit.xpm +352 -0
- data/lib/gui/gtk-remove.xpm +123 -0
- data/lib/gui/gtk-save.xpm +214 -0
- data/lib/gui/gtk-stop.xpm +344 -0
- data/lib/gui/help.xpm +463 -0
- data/lib/gui/icon.xpm +300 -0
- data/lib/gui/message_dialog.rb +34 -0
- data/lib/gui/okay.xpm +49 -0
- data/lib/gui/preferences-color.xpm +252 -0
- data/lib/gui/view.xpm +75 -0
- data/lib/html2text.rb +177 -0
- data/lib/icon/icon.xpm +300 -0
- data/lib/icon/icon_big.xpm +661 -0
- data/lib/license.rb +705 -0
- data/lib/log.conf +65 -0
- data/lib/logging.rb +193 -0
- data/lib/tag_munging.rb +97 -0
- data/lib/translating.rb +78 -0
- data/lib/translations +598 -0
- data/lib/version.rb +26 -0
- metadata +213 -0
data/lib/cfprawn.rb
ADDED
@@ -0,0 +1,394 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
/***************************************************************************
|
4
|
+
* ©2011-2014 Michael Uplawski <michael.uplawski@uplawski.eu> *
|
5
|
+
* *
|
6
|
+
* This program is free software; you can redistribute it and/or modify *
|
7
|
+
* it under the terms of the GNU General Public License as published by *
|
8
|
+
* the Free Software Foundation; either version 3 of the License, or *
|
9
|
+
* (at your option) any later version. *
|
10
|
+
* *
|
11
|
+
* This program is distributed in the hope that it will be useful, *
|
12
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
13
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
14
|
+
* GNU General Public License for more details. *
|
15
|
+
* *
|
16
|
+
* You should have received a copy of the GNU General Public License *
|
17
|
+
* along with this program; if not, write to the *
|
18
|
+
* Free Software Foundation, Inc., *
|
19
|
+
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
20
|
+
***************************************************************************/
|
21
|
+
=end
|
22
|
+
require 'prawn'
|
23
|
+
require 'prawn/table'
|
24
|
+
require 'escape'
|
25
|
+
require_relative 'logging'
|
26
|
+
require_relative 'configuration'
|
27
|
+
require_relative 'translating'
|
28
|
+
require_relative 'html2text'
|
29
|
+
|
30
|
+
# NS_POS=1
|
31
|
+
# TAG_POS=2
|
32
|
+
# CODE_POS=0
|
33
|
+
|
34
|
+
|
35
|
+
# An object of this class wrapps the Prawn PDF generator to convert a single
|
36
|
+
# message from an eml-file to PDF.
|
37
|
+
class CFPrawn
|
38
|
+
include Prawn
|
39
|
+
include Translating
|
40
|
+
include Logging
|
41
|
+
|
42
|
+
@@DEF_LINK_COLOR='008000'
|
43
|
+
@@DEF_REPLACEMENT_COLOR='808080'
|
44
|
+
@@DEF_CONTENT_TYPE_COLOR='000080'
|
45
|
+
@@DEF_REPLACEMENT="<?>"
|
46
|
+
public
|
47
|
+
# initialize a CFPrawn instance, prepare the tag-handlers
|
48
|
+
# for the processing of HTML-mail and begin splitting up the
|
49
|
+
# message into body, headers, attachments.
|
50
|
+
# Treat all of that some way or other to create a PDF-document.
|
51
|
+
def initialize(mail, path)
|
52
|
+
init_logger($CONF.log_file ? $CONF.log_file : STDOUT, $CONF.log_level ? $CONF.log_level : Logger::UNKNOWN)
|
53
|
+
pfx = $CONF.pdf_prefix
|
54
|
+
sfx = $CONF.pdf_suffix
|
55
|
+
page_size = $CONF.page_size
|
56
|
+
page_size ||= 'A4'
|
57
|
+
|
58
|
+
page_layout = $CONF.page_layout
|
59
|
+
page_layout ||= 'portrait'
|
60
|
+
|
61
|
+
@msg = nil
|
62
|
+
@doc = Document.new(:page_size => page_size, :page_layout => page_layout.to_sym)
|
63
|
+
@parts_count = 0
|
64
|
+
@headers = mail.headers ? mail.headers : []
|
65
|
+
begin
|
66
|
+
@log.debug(trl("headers are %s") %[@headers.join(', ')])
|
67
|
+
rescue Exception => e
|
68
|
+
@log.warn(trl("Found a potential problem with the mail-headers.") << " " << e.message)
|
69
|
+
end
|
70
|
+
@body = mail.body
|
71
|
+
@attachments = mail.attachments
|
72
|
+
@attachment_option = $CONF.save_attachments
|
73
|
+
@attachment_option ||= false
|
74
|
+
check_fonts
|
75
|
+
render
|
76
|
+
@outfile = path.dup << File::Separator << (pfx ? pfx : '') << File::basename(mail.filename) << (sfx ? sfx : '') << '.pdf'
|
77
|
+
@log.debug(Translating::trl("writing file %s") %outfile )
|
78
|
+
|
79
|
+
if(@attachment_option && !@attachments.empty? )
|
80
|
+
if('pdf' == @attachment_option)
|
81
|
+
# create PDF, attach files
|
82
|
+
@doc.render_file(@outfile)
|
83
|
+
handle_attachments(@outfile)
|
84
|
+
else
|
85
|
+
# create attachment-files, link, then create PDF
|
86
|
+
handle_attachments(@outfile)
|
87
|
+
@doc.render_file(@outfile)
|
88
|
+
end
|
89
|
+
else
|
90
|
+
# create directly PDF, ignore attachments.
|
91
|
+
@doc.render_file(@outfile)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
# Finds font-files and defines the font-settings for the
|
95
|
+
# PDF.
|
96
|
+
def check_fonts()
|
97
|
+
|
98
|
+
user_font = {}
|
99
|
+
# ***BUGFIX*** Story: if one font-file does not exist, but the other does,
|
100
|
+
# use both anyway and crash.
|
101
|
+
# READ TWICE: I AM TOO DUMB TO PROGRAM !
|
102
|
+
msg = trl('user-defined fonts cannot be applied please verify your configuration.')
|
103
|
+
|
104
|
+
{:normal=>$CONF.regular_font, :bold=>$CONF.bold_font, :italic=>$CONF.italic_font, :bold_itlic=>$CONF.bold_italic_font}.each_pair do |fs, font|
|
105
|
+
if(font && !font.strip.empty?)
|
106
|
+
if(File.exist?(font ))
|
107
|
+
user_font[fs] = font
|
108
|
+
else
|
109
|
+
msg << " (" << trl("font-file '%s' does not exist") %(font ? font.to_s : ' NIL ') << ")"
|
110
|
+
@log.warn(msg)
|
111
|
+
# do not use *ANY* user-defined font
|
112
|
+
return
|
113
|
+
end
|
114
|
+
else
|
115
|
+
@log.warn(msg)
|
116
|
+
return
|
117
|
+
end
|
118
|
+
end
|
119
|
+
@doc.font_families.update("user_font" => user_font) if !user_font.empty?
|
120
|
+
@doc.font("user_font") if !user_font.empty?
|
121
|
+
@log.debug("using fonts: " << @doc.font_families.inspect)
|
122
|
+
end
|
123
|
+
# Delegates method-calls to Prawn, or not.
|
124
|
+
def method_missing(m, *args)
|
125
|
+
@log.debug('method missing ' << m.to_s << '( ' << args.join(', ') << ')')
|
126
|
+
if(@doc.respond_to?(m) )
|
127
|
+
@doc.send(m, *args)
|
128
|
+
else
|
129
|
+
@msg = trl("The method %s is not defined for objects of type %s") %[m, self.class.name]
|
130
|
+
@log.error(@msg)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
private
|
135
|
+
# handles attachment-files in the way, that is configured by the users.
|
136
|
+
def handle_attachments(outfile)
|
137
|
+
new_out = outfile.dup << '_attachment'
|
138
|
+
attachment_files = []
|
139
|
+
|
140
|
+
@log.debug('@attachment_option is ' << @attachment_option.to_s)
|
141
|
+
|
142
|
+
if('pdf' == @attachment_option )
|
143
|
+
if($Progs['pdftk'])
|
144
|
+
dir = File.dirname(outfile) + File::Separator
|
145
|
+
fl = ""
|
146
|
+
@attachments.each do |at|
|
147
|
+
fl = dir.dup << at.filename
|
148
|
+
@log.debug('writing attachment-file ' << fl)
|
149
|
+
File.write(fl, at.decoded)
|
150
|
+
# add quote-marks to file-names.
|
151
|
+
attachment_files << ("%s" %fl )
|
152
|
+
end
|
153
|
+
|
154
|
+
# cmd = Escape.shell_command(["pdftk", pdf, "update_info", info_file, "output", t_file]).to_s
|
155
|
+
cmd = Escape.shell_command(["pdftk", outfile, "attach_files", *attachment_files, "output", new_out]).to_s
|
156
|
+
# cmd = "pdftk \"#{outfile}\" attach_files #{attachment_files.join(' ' )} output \"#{new_out}\""
|
157
|
+
|
158
|
+
@log.debug('executing ' << cmd)
|
159
|
+
if(! system cmd)
|
160
|
+
@msg = trl("Failed to attach files with pdftk (%s)." %($?.exitstatus) )
|
161
|
+
@log.error(@msg)
|
162
|
+
end
|
163
|
+
begin
|
164
|
+
# remove quote-marks from the file-name prior deletion.
|
165
|
+
attachment_files.each {|f| File.delete(f.gsub("\"", '') ) }
|
166
|
+
rescue Exception => ex
|
167
|
+
@msg = trl("Trying to remove an attachment file resulted in an error (%s)") %ex.message
|
168
|
+
@log.error(@msg)
|
169
|
+
end
|
170
|
+
if($?.success? && File.exist?(new_out) )
|
171
|
+
begin
|
172
|
+
File.unlink(outfile)
|
173
|
+
rescue Exception => ex
|
174
|
+
@msg = trl("Trying to remove a file resulted in an error (%s)") %ex.message
|
175
|
+
@log.error(@msg)
|
176
|
+
end
|
177
|
+
File.rename(new_out, outfile)
|
178
|
+
else
|
179
|
+
@log.warn(trl("Trying to attach files to %s, the call to pdftk returned with exit-status %s") %[outfile, $?.exitstatus])
|
180
|
+
end
|
181
|
+
else
|
182
|
+
@log.warn(trl("PDF attachments are requested, but the pdftk-utility has not been found! Ignoring the attachments."))
|
183
|
+
end
|
184
|
+
else
|
185
|
+
if(File.exist?(@attachment_option) && File.directory?(@attachment_option) )
|
186
|
+
fc = 0
|
187
|
+
@attachments.each do |at|
|
188
|
+
@log.debug('handling attachment: ' << at.filename)
|
189
|
+
@log.debug(at[:content_type])
|
190
|
+
ctype = ''
|
191
|
+
begin
|
192
|
+
ctype = at[:content_type].to_s.split('/')[1].split(';')[0]
|
193
|
+
rescue Exception=>ex
|
194
|
+
@log.warn("a problem was encounterd in analyzing the content-type of an attachment: " << ex.message)
|
195
|
+
end
|
196
|
+
@log.debug('attachment, content-type: ' << ctype) if ctype
|
197
|
+
fl = @attachment_option.dup << File::Separator << at.filename
|
198
|
+
File.write(fl, at.decoded)
|
199
|
+
if(File.exist?(fl) )
|
200
|
+
fc += 1
|
201
|
+
if(fc == 1)
|
202
|
+
text(' ')
|
203
|
+
text("<b>" << trl("Attached files") << ":</b>" , :inline_format=>true)
|
204
|
+
end
|
205
|
+
link_color = $CONF.attachment_link_color
|
206
|
+
link_color ||= @@DEF_LINK_COLOR
|
207
|
+
@log.debug('link color is ' << '#' << link_color.to_str)
|
208
|
+
text(format("%i) %s: <link href='file://%s'><u><color rgb='%s'>%s</color></u></link>", fc, ctype, fl, '#' << link_color, at.filename), :inline_format=>true)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
@log.info(trl("Have saved %s of %s attachments to %s") %[fc, @attachments.size, @attachment_option] )
|
212
|
+
else
|
213
|
+
@msg = trl("The value of option 'save attachments' is not a valid directory-name (%s)!" ) %[@attachment_option]
|
214
|
+
@log.error(@msg)
|
215
|
+
end
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
# handles mail-headers and the mail-body
|
220
|
+
def render()
|
221
|
+
if (@headers && !@headers.empty? )
|
222
|
+
@log.debug('writing headers')
|
223
|
+
write_headers()
|
224
|
+
end
|
225
|
+
|
226
|
+
if (@body && !@body.empty?)
|
227
|
+
body_parts(@body)
|
228
|
+
end
|
229
|
+
end
|
230
|
+
# handles one 'part' of a message. Will be
|
231
|
+
# called for each 'part' of a multipart-message.
|
232
|
+
def write_part(btext, content_type = nil)
|
233
|
+
move_down(20)
|
234
|
+
if(content_type)
|
235
|
+
if(@parts_count >= 1)
|
236
|
+
start_new_page
|
237
|
+
end
|
238
|
+
if($CONF.show_content_type)
|
239
|
+
ct_color = $CONF.content_type_color
|
240
|
+
@log.debug('read content-type-color from config ' << ct_color) if ct_color
|
241
|
+
ct_color ||= @@DEF_CONTENT_TYPE_COLOR
|
242
|
+
@log.debug('using content-type-color ' << ct_color)
|
243
|
+
text(format("<u><b><color rgb='%s'>%s</color></b></u>", '#' << ct_color, content_type), :inline_format=>true)
|
244
|
+
move_down(5)
|
245
|
+
end
|
246
|
+
end
|
247
|
+
begin
|
248
|
+
@log.debug('btext is ' << btext)
|
249
|
+
text(btext.encode!("UTF-8"), :inline_format=>true)
|
250
|
+
rescue Exception=>ex
|
251
|
+
@log.warn(ex.message)
|
252
|
+
nt = ''
|
253
|
+
replacement = $CONF.replacement_char
|
254
|
+
replacement ||= @@DEF_REPLACEMENT
|
255
|
+
replacement.gsub!('<', '<')
|
256
|
+
if(btext.respond_to?(:each_char))
|
257
|
+
btext.each_char do |c|
|
258
|
+
begin
|
259
|
+
# a last hope
|
260
|
+
nt << c.encode('ASCII').encode('UTF-8')
|
261
|
+
rescue Exception => ex
|
262
|
+
# now I give up.
|
263
|
+
col = $CONF.replacement_color
|
264
|
+
if(! col || col.size != 6)
|
265
|
+
#col = '808080'
|
266
|
+
col = @@DEF_REPLACEMENT_COLOR
|
267
|
+
end
|
268
|
+
nt << format("<color rgb='%s'>%s</color>", '#' << col, replacement)
|
269
|
+
@log.warn(trl("encoding of a character failed (%s)!") %ex.message )
|
270
|
+
end
|
271
|
+
end
|
272
|
+
end
|
273
|
+
text(nt, :inline_format=>true)
|
274
|
+
ensure
|
275
|
+
@parts_count +=1
|
276
|
+
end
|
277
|
+
end
|
278
|
+
# handles an email according to content-type, the fact that it
|
279
|
+
# is a multipart-message or not. This is tricky and I am not sure
|
280
|
+
# to have understood everything. If something goes wrong, look here, first.
|
281
|
+
def body_parts(part)
|
282
|
+
content_type = part.content_type if part.respond_to?(:content_type)
|
283
|
+
@log.debug('part_content_type is ' << content_type) if content_type
|
284
|
+
content_type ||= @content_type
|
285
|
+
@log.debug('part_content_type will be ' << content_type) if content_type
|
286
|
+
# recursively handle all body-parts, let the body-text grow
|
287
|
+
if(part.multipart? && !part.parts.empty? )
|
288
|
+
part.parts.each do |p|
|
289
|
+
body_parts(p) if !p.attachment?
|
290
|
+
end
|
291
|
+
elsif !part.respond_to?(:content_type) || part.content_type && part.content_type.include?('text')
|
292
|
+
# detect or set the charset
|
293
|
+
# --- from the content-type of the body-part
|
294
|
+
charset = content_type.split(';').detect {|ct| ct.include?('charset')} if content_type
|
295
|
+
charset = charset.split('=')[1] if charset
|
296
|
+
charset = charset.strip.gsub('"', '') if charset
|
297
|
+
# --- from a previously set content-header, if applicable
|
298
|
+
charset ||= @charset
|
299
|
+
# --- or deduce from the encoding of the body-part.
|
300
|
+
# @log.debug('charset is ' << (charset ? charset : 'NIL') )
|
301
|
+
if(!charset && part.respond_to?(:encoding) )
|
302
|
+
# @log.debug('part.encoding is ' << part.encoding)
|
303
|
+
charset = part.encoding
|
304
|
+
end
|
305
|
+
charset = nil if charset && charset.upcase == 'QUOTED-PRINTABLE'
|
306
|
+
charset = (charset.downcase == '8bit' ? 'iso-8859-1' : charset ) if charset
|
307
|
+
charset = (charset.downcase == '7bit' ? 'ASCII' : charset) if charset
|
308
|
+
# Inshallah
|
309
|
+
btext = part.decoded
|
310
|
+
@log.debug('decoded part is ' << btext)
|
311
|
+
# Decoding leaves the text without an encoding (ASCII-8BIT or binary).
|
312
|
+
# Enforce the charset, if one was found above.
|
313
|
+
if(charset && "UTF-8" != btext.encoding.name)
|
314
|
+
@log.debug('trying to force_encode to ' << charset.upcase)
|
315
|
+
btext = btext.force_encoding(charset.upcase)
|
316
|
+
end
|
317
|
+
@log.debug('btext-encoding is now ' << btext.encoding.to_s)
|
318
|
+
# this should not be needed.
|
319
|
+
replacement = $CONF.replacement_char
|
320
|
+
@log.debug('replacement is: ' << replacement)
|
321
|
+
if !replacement
|
322
|
+
replacement = @@DEF_REPLACEMENT
|
323
|
+
end
|
324
|
+
@log.debug('charset will be ' << (charset ? charset : 'NIL') )
|
325
|
+
# if charset
|
326
|
+
# btext.encode!(charset.upcase, :undef=>:replace, :invalid=>:replace, :replace=>replacement)
|
327
|
+
# end
|
328
|
+
|
329
|
+
if(content_type && content_type.include?("text/html"))
|
330
|
+
# replace text by a modified version
|
331
|
+
htext = html(btext)
|
332
|
+
write_part( htext, content_type)
|
333
|
+
else
|
334
|
+
write_part(btext, content_type)
|
335
|
+
end
|
336
|
+
end
|
337
|
+
end
|
338
|
+
|
339
|
+
# handles html-text
|
340
|
+
def html(html)
|
341
|
+
parser = Html2Text.new(html)
|
342
|
+
phtml = parser.text()
|
343
|
+
return phtml
|
344
|
+
end
|
345
|
+
# extracts those headers that should appear in the final PDF-document
|
346
|
+
# and includes them for rendering in the PDF.
|
347
|
+
def write_headers()
|
348
|
+
encs = %w"UTF-8 utf-8 ISO-8859-1 iso-8859-1 ISO-8859-15 iso-8859-15"
|
349
|
+
hcount = @headers.size
|
350
|
+
vh = @headers
|
351
|
+
content_type_header = @headers.detect {|h| h.respond_to?(:name) && "Content-Type" == h.name}
|
352
|
+
@content_type = content_type_header.value if content_type_header
|
353
|
+
cset = (content_type_header.value.split(';').detect {|ct| ct.include?('charset' ) } ) if content_type_header
|
354
|
+
cset = cset.split('=')[1] if cset
|
355
|
+
@charset = cset.strip.gsub('"', '').upcase if cset
|
356
|
+
# @log.debug('have charset from header: ' << @charset) if @charset
|
357
|
+
if($CONF && $CONF.visible_headers)
|
358
|
+
vh = @headers.partition {|h| $CONF.visible_headers.include?(h.name)}[0]
|
359
|
+
hcount = vh.size
|
360
|
+
end
|
361
|
+
table_data = []
|
362
|
+
hwidth = 300
|
363
|
+
headr = vh.max do |a,b|
|
364
|
+
if(a.respond_to?(:name) && b.respond_to?(:name))
|
365
|
+
a.name.length <=> b.name.length
|
366
|
+
end
|
367
|
+
end
|
368
|
+
if(headr)
|
369
|
+
length_field = headr.name.dup
|
370
|
+
@doc.font.normalize_encoding!(length_field)
|
371
|
+
hwidth = @doc.width_of(length_field) + 30
|
372
|
+
end
|
373
|
+
@log.debug('prior mangling headers, charset is: ' << (@charset ? @charset : 'N I L') )
|
374
|
+
vh.each do |h|
|
375
|
+
hvalue = h.decoded.dup
|
376
|
+
hvalue.encode!('UTF-8', :undef=>:replace, :invalid=>:replace, :replace=>"<?>")
|
377
|
+
@log.debug('UTF-8 header: ' << hvalue)
|
378
|
+
table_data << ["%s: " %h.name, hvalue] if h.name && hvalue
|
379
|
+
end
|
380
|
+
@log.debug("printed headers are: " << table_data.join("\n"))
|
381
|
+
if(table_data && !table_data.empty?)
|
382
|
+
# TODO: flexibilize with configuration
|
383
|
+
header_table = @doc.make_table(table_data, :cell_style=>{:borders=>[], :inline_format=>false}, :column_widths=>{0=>hwidth})
|
384
|
+
header_table.columns(2).font_style = :bold
|
385
|
+
header_table.draw
|
386
|
+
else
|
387
|
+
@msg = trl('Cannot write mail-headers. Are you sure that this is an EML-file?' )
|
388
|
+
@log.error(@msg)
|
389
|
+
end
|
390
|
+
end
|
391
|
+
public
|
392
|
+
attr_reader :outfile, :headers, :msg
|
393
|
+
end
|
394
|
+
|
data/lib/confcheck.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#encoding: UTF-8
|
3
|
+
=begin
|
4
|
+
/***************************************************************************
|
5
|
+
* ©2011-2014 Michael Uplawski <michael.uplawski@uplawski.eu> *
|
6
|
+
* *
|
7
|
+
* This program is free software; you can redistribute it and/or modify *
|
8
|
+
* it under the terms of the GNU General Public License as published by *
|
9
|
+
* the Free Software Foundation; either version 3 of the License, or *
|
10
|
+
* (at your option) any later version. *
|
11
|
+
* *
|
12
|
+
* This program is distributed in the hope that it will be useful, *
|
13
|
+
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
14
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
15
|
+
* GNU General Public License for more details. *
|
16
|
+
* *
|
17
|
+
* You should have received a copy of the GNU General Public License *
|
18
|
+
* along with this program; if not, write to the *
|
19
|
+
* Free Software Foundation, Inc., *
|
20
|
+
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
21
|
+
***************************************************************************/
|
22
|
+
=end
|
23
|
+
require 'yaml'
|
24
|
+
require_relative "translating"
|
25
|
+
require_relative "logging"
|
26
|
+
require_relative "configuration"
|
27
|
+
|
28
|
+
|
29
|
+
class ConfCheck
|
30
|
+
include Translating
|
31
|
+
include Logging
|
32
|
+
|
33
|
+
@@RD = File.expand_path(File.dirname(__FILE__) ) + File::SEPARATOR if !defined?(@@RD)
|
34
|
+
|
35
|
+
def initialize
|
36
|
+
init_logger($CONF.log_file ? $CONF.log_file : STDOUT, $CONF.log_level ? $CONF.log_level : Logger::UNKNOWN)
|
37
|
+
|
38
|
+
@orig_conf = "#{@@RD}config"
|
39
|
+
if $CONF.has_user_conf
|
40
|
+
@user_conf = $CONF.config_file if @log.level = Logger::DEBUG
|
41
|
+
begin
|
42
|
+
@orig_keys = YAML::load_file(@orig_conf).keys
|
43
|
+
rescue Exception => ex
|
44
|
+
@log.warn(trl("Cannot load the configuration-file %s") %(@orig_conf) << " (" << ex.message << ")");
|
45
|
+
end
|
46
|
+
@user_keys = $CONF.keys
|
47
|
+
else
|
48
|
+
@user_conf = $CONF.user_configuration
|
49
|
+
# @log.warn(trl("There is no user-configuration found in the current user's home-directory. Did you expect something else?") )
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
# Return the differences; by default those that indicate the changes
|
54
|
+
# needed in the user-configuration so that it contains the same keys
|
55
|
+
# as the 'global' or 'original' version of the configuration.
|
56
|
+
def diffs(conf = :user)
|
57
|
+
test_keys = (conf == :user ? @user_keys : @orig_keys)
|
58
|
+
comp_keys = (conf == :user ? @orig_keys : @user_keys)
|
59
|
+
if(test_keys && comp_keys)
|
60
|
+
return {:missing => comp_keys - test_keys, :additional => test_keys - comp_keys}
|
61
|
+
end
|
62
|
+
return nil
|
63
|
+
end
|
64
|
+
|
65
|
+
# Make a backup-copy of the current user-coniguration.
|
66
|
+
# Overwrite the current user-configuration with a copy of the current global/original
|
67
|
+
# configuration-file or create a new user-configuration.
|
68
|
+
def write_user_conf
|
69
|
+
if(@user_conf && File.exist?(@user_conf))
|
70
|
+
backup = @user_conf.dup << '_bak'
|
71
|
+
File.open backup, 'w' do |bc|
|
72
|
+
File.open @user_conf, 'r' do |uc|
|
73
|
+
while uc.gets("\n") do
|
74
|
+
bc << $_
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
copy_file @orig_conf, @user_conf
|
81
|
+
end
|
82
|
+
|
83
|
+
private
|
84
|
+
|
85
|
+
# dumbly copy one textfile "ifl" into the other "ofl"
|
86
|
+
def copy_file(ifl, ofl)
|
87
|
+
begin
|
88
|
+
File.open ifl, 'r' do |inf|
|
89
|
+
@log.debug('opened for reading ' << ifl)
|
90
|
+
begin
|
91
|
+
File.open ofl, 'w' do |outf|
|
92
|
+
@log.debug('opened for writing ' << ofl)
|
93
|
+
while inf.gets("\n") do
|
94
|
+
outf << $_
|
95
|
+
end
|
96
|
+
end
|
97
|
+
rescue Exception => ex
|
98
|
+
@log.error(trl("Cannot open file for writing (%s)") %ex.message )
|
99
|
+
end
|
100
|
+
end
|
101
|
+
rescue Exception => ex
|
102
|
+
@log.error(trl("Cannot open file for reading (%s)") %ex.message )
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
##### TEST #####
|
109
|
+
if __FILE__ == $0
|
110
|
+
cf = ConfCheck.new
|
111
|
+
cf.write_user_conf
|
112
|
+
end
|
data/lib/config
ADDED
@@ -0,0 +1,192 @@
|
|
1
|
+
# Copyright (c) 2011-2014, Michael Uplawski <michael.uplawski@uplawski.eu>
|
2
|
+
#
|
3
|
+
# This program is free software; you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation; either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# This program is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with this program; if not, write to the
|
15
|
+
# Free Software Foundation, Inc.,
|
16
|
+
# 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
17
|
+
# =========================================================================
|
18
|
+
#
|
19
|
+
# In this file, options can be set to contol how Crème Fraîche will create
|
20
|
+
# PDF from EML.
|
21
|
+
|
22
|
+
# Leave intact the three dashes.
|
23
|
+
---
|
24
|
+
# The PDF-prefix and -suffix are added to the name of an eml-file to
|
25
|
+
# create the name of a resulting PDF-file, potentially keeping a numerical
|
26
|
+
# prefix intact: prefix_[num_]eml_suffix.pdf, e.g. mail_3_eml_arch.pdf
|
27
|
+
# Default: empty
|
28
|
+
# Value: a string
|
29
|
+
# pdf prefix: mail_
|
30
|
+
pdf prefix:
|
31
|
+
|
32
|
+
# pdf suffix: _arch
|
33
|
+
pdf suffix:
|
34
|
+
|
35
|
+
# The log-level can be fatal, error, warn, info or debug
|
36
|
+
# Default: UNKNOWN
|
37
|
+
# Value: one of unknown, fatal, error, warn, info or debug
|
38
|
+
log level: info
|
39
|
+
|
40
|
+
# Path to the protocol-file, where the logger-output will
|
41
|
+
# be directed, if configured. When left empty, stdout will
|
42
|
+
# be used.
|
43
|
+
# Default: STDOUT
|
44
|
+
# Value: a file-path
|
45
|
+
#
|
46
|
+
# log file: /tmp/cremefraiche.log
|
47
|
+
# log file:
|
48
|
+
|
49
|
+
# Page-size
|
50
|
+
# Default: A4
|
51
|
+
# Value: One of
|
52
|
+
# 4A0, 2A0, A0, A1, A2, A3, A4, A5, A6, A7,
|
53
|
+
# A8, A9, A10, B0, B1, B2, B3, B4, B5, B6,
|
54
|
+
# B7, B8, B9, B10, C0, C1, C2, C3, C4, C5,
|
55
|
+
# C6, C7, C8, C9, C10, RA0, RA1, RA2, RA3,
|
56
|
+
# RA4, SRA0, SRA1, SRA3, SRA4, EXECUTIVE,
|
57
|
+
# FOLIO, LEGAL, LETTER,
|
58
|
+
page size: A4
|
59
|
+
|
60
|
+
# Page layout
|
61
|
+
# Default: portrait
|
62
|
+
# Value: One of portrait or landscape
|
63
|
+
page layout: portrait
|
64
|
+
|
65
|
+
# Font to use in the PDF-file. By default, the fonts used
|
66
|
+
# in the PDF are those supported by the Ruby-gem "Prawn",
|
67
|
+
# i.e. Courier, Times-Roman and Helvetica or the respective
|
68
|
+
# replacement font, which is valid on your system.
|
69
|
+
#
|
70
|
+
# The font, that you name here, will replace Helvetica and
|
71
|
+
# be used for the headers and the body of the email in
|
72
|
+
# PDF-format.
|
73
|
+
# Default: Helvetica (or its current replacement)
|
74
|
+
# Value: Path to an existing font-file for each
|
75
|
+
# font-style that shall be replaced.
|
76
|
+
# example:
|
77
|
+
# regular font: /usr/share/fonts/truetype/linux-libertine/LinBiolinum_Re.ttf
|
78
|
+
# bold font: /usr/share/fonts/truetype/linux-libertine/LinBiolinum_Bd.ttf
|
79
|
+
regular font:
|
80
|
+
bold font:
|
81
|
+
italic font:
|
82
|
+
bold italic font:
|
83
|
+
|
84
|
+
# The visible headers will be shown in the final pdf.
|
85
|
+
# Headers which are noted here *and* also under hidden
|
86
|
+
# headers, will anyway be honored (*not* ignored).
|
87
|
+
# Default: All headers of a mail
|
88
|
+
# Value: a list of mail-headers
|
89
|
+
visible headers:
|
90
|
+
Date
|
91
|
+
From
|
92
|
+
To
|
93
|
+
Subject
|
94
|
+
|
95
|
+
# The hidden headers will be suppressed... they are
|
96
|
+
# still here for reference. Add more, as you stumble over
|
97
|
+
# new headers in your e-mail.
|
98
|
+
# Headers which are noted here *and* also under visible
|
99
|
+
# headers will anyway be honored (*not* ignored).
|
100
|
+
# Default: empty
|
101
|
+
# Value: a list of mail-headers
|
102
|
+
hidden headers:
|
103
|
+
Message-ID
|
104
|
+
User-Agent
|
105
|
+
MIME-Version
|
106
|
+
Delivered-To
|
107
|
+
Return-Path
|
108
|
+
Received
|
109
|
+
References
|
110
|
+
In-Reply-To
|
111
|
+
X-Enigmail-Version
|
112
|
+
Content-Type
|
113
|
+
Content-Transfer-Encoding
|
114
|
+
|
115
|
+
# This option controls wether a visible body-part is preceded
|
116
|
+
# by a line indicating the content-type, like
|
117
|
+
# "text/plain; charset=ISO-8859-1; format=flowed"
|
118
|
+
# Default: false
|
119
|
+
# Value: true or false
|
120
|
+
show content type: true
|
121
|
+
|
122
|
+
# The color of the content type
|
123
|
+
# Default: '000080'
|
124
|
+
# Value: a hexadecimal rgb-value
|
125
|
+
# in single quotes
|
126
|
+
content type color: '000080'
|
127
|
+
|
128
|
+
# This is the color of a replacement-character, where a
|
129
|
+
# character cannot be converted to UTF-8.
|
130
|
+
# Default: 808080
|
131
|
+
# Value: Hexadecimal rgb color-value
|
132
|
+
# in single quotes
|
133
|
+
replacement color: 'f08080'
|
134
|
+
|
135
|
+
# Symbols which will replace any character which
|
136
|
+
# cannot be converted to UTF-8.
|
137
|
+
# Default: <?>
|
138
|
+
# Value: A String
|
139
|
+
replacement char: <?>
|
140
|
+
|
141
|
+
# Color for hyper-links
|
142
|
+
# Default: '008000'
|
143
|
+
# Value: a hexadecimal rgb-color value
|
144
|
+
# in single quotes
|
145
|
+
link color: '700000'
|
146
|
+
|
147
|
+
# Provided the pdftk-tool is installed and can be found
|
148
|
+
# in the environment path, the value of these variables will
|
149
|
+
# set the respective field in the meta-data of the resulting
|
150
|
+
# PDF-files. Leave empty or comment to ignore...
|
151
|
+
#
|
152
|
+
# Default subject is the subject-line of the original mail.
|
153
|
+
# Default: empty (mail-subject for 'Subject')
|
154
|
+
# Value: A string
|
155
|
+
Author:
|
156
|
+
Subject:
|
157
|
+
Keywords:
|
158
|
+
Title:
|
159
|
+
|
160
|
+
# If and where attachments shall be placed.
|
161
|
+
# Default: false
|
162
|
+
# Value: One of the following
|
163
|
+
# 'pdf' - store files in the PDF (needs pdftk)
|
164
|
+
# The Adobe Acrobat-reader can open
|
165
|
+
# attachments to PDF-files.
|
166
|
+
#
|
167
|
+
# a directory path - store files in the given directory.
|
168
|
+
# A link to the file shall be provided
|
169
|
+
# in the PDF. The directory MUST EXIST.
|
170
|
+
#
|
171
|
+
# 'false' - do not store the attachments
|
172
|
+
# save attachments: /tmp/mail_attachments
|
173
|
+
save attachments: pdf
|
174
|
+
|
175
|
+
# The color of the links to saved attachments, if "save attachments"
|
176
|
+
# above is set to a file path, rather than 'pdf'
|
177
|
+
# Default: '008000'
|
178
|
+
# Value: a hexadecimal rgb-color value
|
179
|
+
# in single quotes
|
180
|
+
attachment link color: '008000'
|
181
|
+
|
182
|
+
# A reader-application which can be used in different contexts to
|
183
|
+
# show a PDF-file.
|
184
|
+
# examples:
|
185
|
+
# pdf reader: evince
|
186
|
+
# pdf reader: okular
|
187
|
+
# pdf reader: c:\Program Files\Acrobat.exe
|
188
|
+
#
|
189
|
+
# Default: empty
|
190
|
+
# Value: the file-path of a program executable.
|
191
|
+
pdf reader:
|
192
|
+
|