cremefraiche 1.1.8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +114 -0
- data/bin/cremefraiche +117 -0
- data/bin/cremefraicheGui +26 -0
- data/cremefraiche.gemspec +24 -0
- data/doc/gui_howto.pdf +0 -0
- data/lib/LANG +1 -0
- data/lib/basic_logging.rb +170 -0
- data/lib/busy_indicator/.busy_function_test.rb.swp +0 -0
- data/lib/busy_indicator/.busy_indicator.rb.swp +0 -0
- data/lib/busy_indicator/.color_output.rb.swp +0 -0
- data/lib/busy_indicator/busy_function_test.rb +50 -0
- data/lib/busy_indicator/busy_indicator.rb +89 -0
- data/lib/busy_indicator/color_output.rb +45 -0
- data/lib/cfprawn.rb +387 -0
- data/lib/confcheck.rb +103 -0
- data/lib/config +187 -0
- data/lib/configuration.rb +234 -0
- data/lib/configuration.rb~ +247 -0
- data/lib/cremefraiche.rb +181 -0
- data/lib/emlfile.rb +136 -0
- data/lib/file_checking.rb +82 -0
- data/lib/gui/.ButtonLabel.rb.swp +0 -0
- data/lib/gui/.conf_value.rb.swp +0 -0
- data/lib/gui/.cremefraicheGui.rb.swp +0 -0
- data/lib/gui/.message_dialog.rb.swp +0 -0
- data/lib/gui/AboutDialog.rb +63 -0
- data/lib/gui/ButtonLabel.rb +41 -0
- data/lib/gui/ConfDialog.rb +610 -0
- data/lib/gui/HowtoDialog.rb +183 -0
- data/lib/gui/conf_option.rb +274 -0
- data/lib/gui/conf_value.rb +58 -0
- data/lib/gui/cremefraicheGui.rb +568 -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 +195 -0
- data/lib/icon/icon.xpm +300 -0
- data/lib/icon/icon_big.xpm +661 -0
- data/lib/license.rb +38 -0
- data/lib/log.conf +65 -0
- data/lib/tag_munging.rb +89 -0
- data/lib/translating.rb +78 -0
- data/lib/translations +609 -0
- data/lib/version.rb +25 -0
- metadata +221 -0
data/lib/emlfile.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
/***************************************************************************
|
4
|
+
* ©2011-2023, 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 WTFPL 2.0 or later version of the LICENSE. *
|
8
|
+
* See https://wtfpl2.com/ for details. *
|
9
|
+
* *
|
10
|
+
* This program 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. *
|
13
|
+
* *
|
14
|
+
***************************************************************************/
|
15
|
+
=end
|
16
|
+
|
17
|
+
require_relative "file_checking"
|
18
|
+
require_relative "translating"
|
19
|
+
require_relative "basic_logging"
|
20
|
+
require 'mail'
|
21
|
+
|
22
|
+
# A representation of an EML-file.
|
23
|
+
# Wraps the Mail-object (from the Mail-gem).
|
24
|
+
class EmlFile
|
25
|
+
include BasicLogging
|
26
|
+
|
27
|
+
BasicLogging::mute(self)
|
28
|
+
include File_Checking
|
29
|
+
include Translating
|
30
|
+
@@MAIL_INTRO = "From "
|
31
|
+
@@errors = []
|
32
|
+
attr_reader :headers, :body, :files, :filename, :msg
|
33
|
+
|
34
|
+
public
|
35
|
+
|
36
|
+
# create the representation of 1 eml-file
|
37
|
+
def initialize(filename)
|
38
|
+
debug 'EMLFile - is ' << inspect
|
39
|
+
debug('log initialized')
|
40
|
+
@attachments = nil
|
41
|
+
@body = nil
|
42
|
+
@headers = nil
|
43
|
+
msg = file_check(filename, :exist, :file, :readable)
|
44
|
+
debug('file checked: ' << msg.to_s)
|
45
|
+
@@errors << msg if msg
|
46
|
+
# split the file into many, one for each e-mail
|
47
|
+
if(!msg)
|
48
|
+
split(filename)
|
49
|
+
else
|
50
|
+
error(trl("Invalid file") << ": %s (%s)" %[filename,msg] )
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
# delegate messages, that this object cannot respond to to the Mail-object
|
55
|
+
def method_missing(method, *args)
|
56
|
+
if(@mail.respond_to?(method) )
|
57
|
+
@mail.send(method, *args)
|
58
|
+
else
|
59
|
+
error(trl("method %s is undefined for objects of class %s") %[method, self.class.name])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
# call the given block on each individual mail-file
|
63
|
+
def mails(&b)
|
64
|
+
if(@files)
|
65
|
+
debug('working on the files: ' << @files.join(', '))
|
66
|
+
@files.each do |f|
|
67
|
+
parse(f)
|
68
|
+
@filename=f
|
69
|
+
yield(self)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
# separate the components of each mail-file
|
77
|
+
def parse(filename)
|
78
|
+
if(filename)
|
79
|
+
@mail = Mail.read(filename)
|
80
|
+
if(@mail )
|
81
|
+
@headers = @mail.header_fields
|
82
|
+
# debug('Parsed headers are ' << @headers.join(', ') )
|
83
|
+
@body = @mail.body
|
84
|
+
# debug('Parsed body is ' << @body.to_s )
|
85
|
+
@attachments = @mail.attachments if @mail.attachment?
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# prefix the number num with a maximum of count_zero zeros
|
91
|
+
def prefix_number(num, count_zero = 2)
|
92
|
+
str = ''
|
93
|
+
if(num)
|
94
|
+
str = num.to_s
|
95
|
+
count_zero.times do
|
96
|
+
if(num % 10 == num)
|
97
|
+
str = ('0' << str )
|
98
|
+
debug('str is now ' << str)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
return str
|
103
|
+
end
|
104
|
+
|
105
|
+
# split the file 'filename' into separate files, each containing 1 mail
|
106
|
+
def split(filename)
|
107
|
+
dir = $CONF.temp_dir
|
108
|
+
debug(trl("storing temporary files in %s") %dir.path)
|
109
|
+
index = 0
|
110
|
+
@files = []
|
111
|
+
begin
|
112
|
+
File.open(filename, 'r') do |ifl|
|
113
|
+
ofl = nil
|
114
|
+
ifl.each_line do |line|
|
115
|
+
if(line.start_with?(@@MAIL_INTRO))
|
116
|
+
ofl.close if ofl && !ofl.closed?
|
117
|
+
index += 1
|
118
|
+
ofl_name = format("%s/%s_%s" %[dir.path, prefix_number(index, 2), File.basename(filename)])
|
119
|
+
debug(trl("storing a message in %s") %ofl_name)
|
120
|
+
ofl = File.open(ofl_name, 'w')
|
121
|
+
@files << ofl_name
|
122
|
+
end
|
123
|
+
ofl << line if ofl && !ofl.closed?
|
124
|
+
end
|
125
|
+
ofl.close if ofl && !ofl.closed?
|
126
|
+
end
|
127
|
+
rescue Exception => ex
|
128
|
+
error(trl("Cannot open file '%s'") %filename << ': ' << ex.message )
|
129
|
+
end
|
130
|
+
# a single e-mail can be stored in its own file
|
131
|
+
if(@files.empty? && File::exist?(filename) && File::readable?(filename) )
|
132
|
+
@files << filename
|
133
|
+
end
|
134
|
+
end # END split()
|
135
|
+
end # END of class
|
136
|
+
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
|
3
|
+
=begin
|
4
|
+
/***************************************************************************
|
5
|
+
* ©2023-2023, 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 WTFPL 2.0 or later version of the LICENSE. *
|
9
|
+
* See https://wtfpl2.com/ for details. *
|
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. *
|
14
|
+
* *
|
15
|
+
***************************************************************************/
|
16
|
+
=end
|
17
|
+
|
18
|
+
=begin
|
19
|
+
A module to facilitate frequently occuring checks on
|
20
|
+
file-system objects
|
21
|
+
=end
|
22
|
+
module File_Checking
|
23
|
+
|
24
|
+
@@text_messages = {
|
25
|
+
:exist? => "does not exist!",
|
26
|
+
:exist => "does not exist!",
|
27
|
+
:readable? => "is not readable!",
|
28
|
+
:readable => "is not readable!",
|
29
|
+
:executable? => "is not executable!",
|
30
|
+
:executable => "is not executable!",
|
31
|
+
:writable? => "is not writable!",
|
32
|
+
:writable => "is not writable!",
|
33
|
+
:directory? => "is not a directory!",
|
34
|
+
:directory => "is not a directory!",
|
35
|
+
:file? => "is not a file!",
|
36
|
+
:file => "is not a file!",
|
37
|
+
}
|
38
|
+
|
39
|
+
# Checks if the file with the name from the first
|
40
|
+
# parameter has the properties, listed in the second.
|
41
|
+
# The messages parameter is an array of one or several
|
42
|
+
# of :exist?, :readable?, :writable?, :directory? or
|
43
|
+
# their string-representations, respectively.
|
44
|
+
# Returns nil in case of success, otherwise an
|
45
|
+
# informative message, describing the first negative
|
46
|
+
# test-result.
|
47
|
+
def file_check(file, *messages)
|
48
|
+
File_Checking.file_check(file, *messages)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Checks if the file with the name from the first
|
52
|
+
# parameter has the properties, listed in the second.
|
53
|
+
# The messages parameter is an array of one or all
|
54
|
+
# of :exist?, :readable?, :writable?, :directory? or
|
55
|
+
# their string-representations, respectively.
|
56
|
+
# Returns nil in case of success, otherwise an
|
57
|
+
# informative message, describing the first negative
|
58
|
+
# test-result.
|
59
|
+
def self.file_check(file, *messages)
|
60
|
+
msg = nil
|
61
|
+
if(file && messages.respond_to?(:to_ary) && !messages.empty?)
|
62
|
+
messages.each do |k|
|
63
|
+
if(! k.to_s.end_with?('?'))
|
64
|
+
k = (k.to_s << '?').to_sym
|
65
|
+
end
|
66
|
+
@log.debug ('checking ' << k.to_s) if @log
|
67
|
+
if(msg == nil && File.respond_to?(k) && ! File.send(k, file.to_s))
|
68
|
+
msg = "#{file} #{@@text_messages[k.to_sym]}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
msg
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
=begin
|
77
|
+
# example
|
78
|
+
|
79
|
+
include File_Checking
|
80
|
+
msg = file_check('some_file.txt', [:exist?, :readable?, 'writable'])
|
81
|
+
puts msg if msg
|
82
|
+
=end
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,63 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
/***************************************************************************
|
4
|
+
* ©2011-2023, 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 WTFPL 2.0 or later version of the LICENSE. *
|
8
|
+
* See https://wtfpl2.com/ for details. *
|
9
|
+
* *
|
10
|
+
* This program 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. *
|
13
|
+
* *
|
14
|
+
***************************************************************************/
|
15
|
+
=end
|
16
|
+
require 'gtk3'
|
17
|
+
require_relative '../cremefraiche'
|
18
|
+
require_relative '../translating'
|
19
|
+
require_relative '../file_checking'
|
20
|
+
require_relative '../license.rb'
|
21
|
+
require_relative '../basic_logging.rb'
|
22
|
+
|
23
|
+
GD = File::expand_path(File::dirname(__FILE__) ) + File::Separator if !defined?(GD)
|
24
|
+
|
25
|
+
class AboutDialog
|
26
|
+
include Translating
|
27
|
+
include BasicLogging
|
28
|
+
|
29
|
+
@@prog_info = CremeFraiche::prog_info
|
30
|
+
# prevent repeated appending of the comments
|
31
|
+
@@info = Translating::trl('running with Ruby') << ' ' << RUBY_VERSION << ' (' << RUBY_RELEASE_DATE << ') '
|
32
|
+
@@info << RUBY_PLATFORM << "\n\n" << Translating::trl('Current system') << ': ' << @@prog_info[:cur_system]
|
33
|
+
|
34
|
+
@@License_File = GD.dup << '../doc/license.txt'
|
35
|
+
|
36
|
+
# FED UP WITH GTK !!
|
37
|
+
CLS = -4
|
38
|
+
def initialize( options = {})
|
39
|
+
|
40
|
+
@adialog = Gtk::AboutDialog.new
|
41
|
+
@adialog.name = @@prog_info[:app_name]
|
42
|
+
@adialog.title = @@prog_info[:app_name]
|
43
|
+
@adialog.set_program_name @@prog_info[:app_name]
|
44
|
+
@adialog.version = @@prog_info[:version]
|
45
|
+
@adialog.copyright = "© #{@@prog_info[:years]} #{@@prog_info[:author]} #{@@prog_info[:author_mail]}"
|
46
|
+
@adialog.website = "#{@@prog_info[:web_page]}"
|
47
|
+
|
48
|
+
@adialog.comments = @@info
|
49
|
+
@adialog.license = LICENSE_TEXT
|
50
|
+
@adialog.logo = GdkPixbuf::Pixbuf.new(:file => GD + "icon.xpm")
|
51
|
+
@adialog.signal_connect('response') do |dlg, resp|
|
52
|
+
debug("response %i emitted" %resp)
|
53
|
+
# I am fed up with the Gtk docuentation
|
54
|
+
@adialog.close if(CLS == resp)
|
55
|
+
end
|
56
|
+
if(options && options.keys.include?(:on_destroy))
|
57
|
+
@adialog.signal_connect('destroy') {options[:on_destroy].call() }
|
58
|
+
end
|
59
|
+
@adialog.show
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#encoding: UTF-8
|
2
|
+
=begin
|
3
|
+
/***************************************************************************
|
4
|
+
* ©2011-2023, 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 WTFPL 2.0 or later version of the LICENSE. *
|
8
|
+
* See https://wtfpl2.com/ for details. *
|
9
|
+
* *
|
10
|
+
* This program 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. *
|
13
|
+
* *
|
14
|
+
***************************************************************************/
|
15
|
+
=end
|
16
|
+
require_relative '../basic_logging.rb'
|
17
|
+
require 'gtk3'
|
18
|
+
require_relative '../translating'
|
19
|
+
|
20
|
+
=begin
|
21
|
+
Meant to be used as label for push-buttons,
|
22
|
+
objects of this class combine a text-value
|
23
|
+
with a user-provided icon.
|
24
|
+
=end
|
25
|
+
class ButtonLabel < Gtk::Box
|
26
|
+
include BasicLogging
|
27
|
+
def initialize(text, imagefile = nil)
|
28
|
+
super(:horizontal, 5)
|
29
|
+
set_border_width(0)
|
30
|
+
pack_start(Gtk::Image.new(:file => imagefile)) if imagefile
|
31
|
+
@mlabel = Gtk::Label.new( text, :mnemonic => true)
|
32
|
+
@mlabel.markup_with_mnemonic=text
|
33
|
+
# debug(@mlabel.mnemonic_keyval)
|
34
|
+
pack_start(@mlabel)
|
35
|
+
end
|
36
|
+
|
37
|
+
def mnemonic_widget=(wd)
|
38
|
+
@mlabel.mnemonic_widget=(wd)
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|