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
@@ -0,0 +1,259 @@
|
|
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
|
+
|
23
|
+
require_relative 'file_checking'
|
24
|
+
require 'singleton'
|
25
|
+
require 'yaml'
|
26
|
+
require_relative 'logging'
|
27
|
+
|
28
|
+
# An object of the Configuration class reads and exposes options from a
|
29
|
+
# configuration-file in YAML format.
|
30
|
+
class Configuration
|
31
|
+
include File_Checking
|
32
|
+
include Singleton
|
33
|
+
include Logging
|
34
|
+
@@RD = File::expand_path(File::dirname(__FILE__) ) + File::Separator if !defined?(@@RD)
|
35
|
+
@@config_file = "#{@@RD}config"
|
36
|
+
@@USER_CONF_DIR = File::join(ENV['HOME'].dup, '.cremefraiche' )
|
37
|
+
@@USER_CONF = File::join(@@USER_CONF_DIR.dup, 'config')
|
38
|
+
|
39
|
+
# initialize the singleton-instance and read the configuration-
|
40
|
+
# file.
|
41
|
+
def initialize
|
42
|
+
# Temporary logger. Will be replaced.
|
43
|
+
@log = Logger.new(STDOUT)
|
44
|
+
@log.level = Logger::INFO
|
45
|
+
@log.info('init config')
|
46
|
+
read_config
|
47
|
+
check_programs_installed
|
48
|
+
# here...
|
49
|
+
init_logger(@conf['log_file'] ? @conf['log_file'] : STDOUT, @conf['log_level'] ? @conf['log_level'] : Logger::UNKNOWN)
|
50
|
+
end
|
51
|
+
def save_config(conf)
|
52
|
+
yml = conf.to_yaml
|
53
|
+
@log.debug('yaml will be ' << yml)
|
54
|
+
if (! Dir.exist?(@@USER_CONF_DIR) )
|
55
|
+
Dir.mkdir(@@USER_CONF_DIR)
|
56
|
+
end
|
57
|
+
File.open(@@USER_CONF, 'w') do |cf|
|
58
|
+
cf << yml
|
59
|
+
end
|
60
|
+
end
|
61
|
+
def to_s
|
62
|
+
str = @conf.to_s
|
63
|
+
@log.debug(str)
|
64
|
+
return str
|
65
|
+
end
|
66
|
+
|
67
|
+
# used to extract values from the confiuration-file
|
68
|
+
def method_missing(method, *args)
|
69
|
+
# @log.debug('method missing ' << method.to_s << '(' << args.join(', ') << ')')
|
70
|
+
key = method.to_s.gsub('_', ' ')
|
71
|
+
if(@conf && key)
|
72
|
+
co = @conf[key]
|
73
|
+
# @log.debug('returning conf-option ' << (co && !co.to_s.empty? ? co.to_s : 'nil'))
|
74
|
+
return (co && !co.to_s.empty? ? co : nil)
|
75
|
+
else
|
76
|
+
@log.error(trl("Unable to read an option from the configuration"))
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# returns the path to the configuration-file
|
81
|
+
def config_file
|
82
|
+
@@config_file
|
83
|
+
end
|
84
|
+
|
85
|
+
def size
|
86
|
+
@conf.size
|
87
|
+
end
|
88
|
+
|
89
|
+
def each_with_index(&b)
|
90
|
+
@conf.each_with_index do |pair, i|
|
91
|
+
yield(pair, i)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def each_pair(&b)
|
96
|
+
@conf.each_pair do |k, v|
|
97
|
+
yield(k, v)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# Creates a temporary directory upon the first call but always returns its path
|
102
|
+
# Stolen from Alex Chaffee's files-gem and
|
103
|
+
# http://stackoverflow.com/questions/1139265/what-is-the-best-way-to-get-a-temporary-directory-in-ruby-on-rails
|
104
|
+
def temp_dir options = {:remove => true}
|
105
|
+
@temp_dir ||= begin
|
106
|
+
@log.debug('creating temp_dir')
|
107
|
+
require 'tmpdir'
|
108
|
+
require 'fileutils'
|
109
|
+
#
|
110
|
+
# called_from = File.basename caller.first.split(':').first, ".rb"
|
111
|
+
called_from = CremeFraiche::prog_info[:app_name].gsub(' ', '_')
|
112
|
+
@log.debug('called_from is ' << called_from)
|
113
|
+
path = File.join(Dir::tmpdir, "#{called_from}_#{Time.now.to_i}_#{rand(1000)}")
|
114
|
+
@log.debug('temp-dir path is ' << path)
|
115
|
+
Dir.mkdir(path)
|
116
|
+
at_exit {FileUtils.rm_rf(path) if File.exists?(path)} if options[:remove]
|
117
|
+
File.new path
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def read_config
|
122
|
+
# replace the globally defined configuration file by a
|
123
|
+
# user-provided version, if available.
|
124
|
+
# -----> here
|
125
|
+
@has_user_conf = user_conf
|
126
|
+
# <------
|
127
|
+
msg = file_check(@@config_file, :exist, :readable)
|
128
|
+
if(!msg)
|
129
|
+
@log.info('configuration will be read from ' << @@config_file)
|
130
|
+
begin
|
131
|
+
@conf = YAML::load_file(@@config_file)
|
132
|
+
@keys = @conf.keys
|
133
|
+
if(@keys.include?('log level') )
|
134
|
+
@log_level = case @conf['log level'].downcase
|
135
|
+
when 'debug'
|
136
|
+
Logger::DEBUG
|
137
|
+
when 'fatal'
|
138
|
+
Logger::FATAL
|
139
|
+
when 'error'
|
140
|
+
Logger::ERROR
|
141
|
+
when 'info'
|
142
|
+
Logger::INFO
|
143
|
+
when 'warn'
|
144
|
+
Logger::WARN
|
145
|
+
else
|
146
|
+
Logger::UNKNOWN
|
147
|
+
end
|
148
|
+
else
|
149
|
+
@log_level = Logger::UNKNOWN
|
150
|
+
end
|
151
|
+
rescue Exception => ex
|
152
|
+
msg = ex.message
|
153
|
+
end
|
154
|
+
if(@conf)
|
155
|
+
init_logger(@conf['log file'] ? @conf['log file'] : STDOUT, @log_level)
|
156
|
+
else
|
157
|
+
@log.fatal('Cannot set the log-level ! @conf is ' << @conf.inspect << '. EXITING!')
|
158
|
+
exit -1
|
159
|
+
end
|
160
|
+
end
|
161
|
+
@log.debug('configuration is ' << @conf.to_s)
|
162
|
+
@log.error(trl("cannot read the configuration-file (%s)") %msg ) if msg
|
163
|
+
|
164
|
+
end
|
165
|
+
|
166
|
+
|
167
|
+
|
168
|
+
attr_reader :log_level
|
169
|
+
attr_reader :has_user_conf
|
170
|
+
attr_reader :keys
|
171
|
+
attr_reader :user_configuration
|
172
|
+
|
173
|
+
private
|
174
|
+
|
175
|
+
# Finds external programs in the environment path.
|
176
|
+
# A decision to use one of those programs depends on the fact,
|
177
|
+
# that they are installed at all. Contradicting options will
|
178
|
+
# result in warning-messages in the protocol output.
|
179
|
+
def check_programs_installed
|
180
|
+
prog_names = %w"pdftk firefox opera epiphany-browser"
|
181
|
+
$Progs = {} if !defined? $Progs
|
182
|
+
pathdirs = ENV['PATH'].split(File::PATH_SEPARATOR).collect do |d|
|
183
|
+
# BUGFIX: PATH may contain just anything!
|
184
|
+
pdir = nil
|
185
|
+
if(Dir.exist?(d) )
|
186
|
+
if(File.readable?(d) )
|
187
|
+
# create a non nil entry for pathdirs.
|
188
|
+
begin
|
189
|
+
pdir = Dir.new(d)
|
190
|
+
rescue Exception => ex
|
191
|
+
# "Trust nobody" (Herod V)
|
192
|
+
@log.error(trl("Cannot search for executables in %s") %d << ': ' << ex.message )
|
193
|
+
end
|
194
|
+
else
|
195
|
+
@log.warn(trl('The path-variable references an unreadable directory') << ': ' << (d ? d.to_s : 'NIL') )
|
196
|
+
end
|
197
|
+
else
|
198
|
+
@log.warn('test')
|
199
|
+
# @log.warn(trl('The path-variable contains an invalid value') << ': ' << (d ? d.to_s : 'NIL') )
|
200
|
+
end
|
201
|
+
# --------> Now this is neat...
|
202
|
+
pdir
|
203
|
+
end
|
204
|
+
# ... or wait ... It is not!
|
205
|
+
# Remove the nil-entries from pathdirs
|
206
|
+
pathdirs.compact!
|
207
|
+
# <------ Now this is neat...
|
208
|
+
|
209
|
+
if(pathdirs && !pathdirs.empty? )
|
210
|
+
@log.debug('path: ' + pathdirs.join(', ') )
|
211
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
212
|
+
|
213
|
+
prog_names.each do |prog|
|
214
|
+
pathdirs.each do |dir|
|
215
|
+
exts.each do |ext|
|
216
|
+
# BUGFIX: Beware of case-variations in the
|
217
|
+
# defined program-extension. Windows-specific.
|
218
|
+
# Thanks to Tijn Gommans for pointing this out.
|
219
|
+
$Progs[prog] |= dir.entries.include?("#{prog}#{ext.upcase}")
|
220
|
+
$Progs[prog] |= dir.entries.include?("#{prog}#{ext.downcase}")
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
end
|
226
|
+
@log.debug("found the following external programs: " << $Progs.to_s)
|
227
|
+
end
|
228
|
+
|
229
|
+
|
230
|
+
# Checks, if a version of the configuration-file had been created in the user's
|
231
|
+
# home-directory and switches to this file, if it exists. Otherwise the original
|
232
|
+
# standard-version is used.
|
233
|
+
def user_conf()
|
234
|
+
# does the HOME-key exist in the environment?
|
235
|
+
home_dir = ENV['HOME']
|
236
|
+
@log.debug('home-directory appears to be: ' << home_dir) if @log
|
237
|
+
if(home_dir )
|
238
|
+
# The user-provided configuration-file is $HOME/.cremefraiche/config
|
239
|
+
|
240
|
+
if(File::exist?(@@USER_CONF) && File.readable?(@@USER_CONF) && File::file?(@@USER_CONF))
|
241
|
+
if File::size(@@USER_CONF) > 100
|
242
|
+
@@config_file = @@USER_CONF
|
243
|
+
return true
|
244
|
+
else
|
245
|
+
@log.error('The configuration-file "' << @@USER_CONF << "\" is empty or too short!\nWill be using configuration from " << @@config_file << '.') if @log
|
246
|
+
end
|
247
|
+
else
|
248
|
+
@log.warn('Cannot use configuration-file ' << @@USER_CONF) if @log
|
249
|
+
@log.warn('Using configuration from ' << @@config_file << '.') if @log
|
250
|
+
|
251
|
+
end
|
252
|
+
end
|
253
|
+
return false
|
254
|
+
end
|
255
|
+
|
256
|
+
|
257
|
+
end
|
258
|
+
|
259
|
+
$CONF = Configuration.instance
|
data/lib/cremefraiche.rb
ADDED
@@ -0,0 +1,341 @@
|
|
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 'rubygems'
|
24
|
+
require_relative "confcheck"
|
25
|
+
require_relative "translating"
|
26
|
+
require_relative "logging"
|
27
|
+
require_relative "configuration"
|
28
|
+
require_relative "version"
|
29
|
+
|
30
|
+
['prawn-table', 'mail', 'prawn', 'nokogiri', 'escape'].each do |g|
|
31
|
+
begin
|
32
|
+
gem g
|
33
|
+
rescue LoadError
|
34
|
+
puts ' => ' << (Translating::trl("PSE wait, installing required gem '%s'") %g)
|
35
|
+
puts ' ' << Translating::trl('This may take some time') << ' ...'
|
36
|
+
begin
|
37
|
+
if !system 'gem install ' << g
|
38
|
+
exit false
|
39
|
+
end
|
40
|
+
rescue Exception => e
|
41
|
+
puts ' ' << (Translating::trl("Cannot install '%s'") %g) << ': ' << e.message
|
42
|
+
exit false
|
43
|
+
end
|
44
|
+
end
|
45
|
+
Gem.clear_paths
|
46
|
+
end
|
47
|
+
require_relative "emlfile"
|
48
|
+
require_relative "cfprawn"
|
49
|
+
require_relative "busy_indicator/busy_indicator"
|
50
|
+
require 'escape'
|
51
|
+
|
52
|
+
$PROG_DIR = File::expand_path(File::dirname(__FILE__) ) << File::Separator if !defined?($PROG_DIR)
|
53
|
+
$ICON_DIR = $PROG_DIR.dup << 'icon' << File::Separator if !defined?($ICON_DIR)
|
54
|
+
@log.debug("PROG_DIR is " << $PROG_DIR) if @log
|
55
|
+
$WIN = (RUBY_PLATFORM =~ /mswin/)
|
56
|
+
|
57
|
+
|
58
|
+
# The main application-class.
|
59
|
+
class CremeFraiche
|
60
|
+
include Translating
|
61
|
+
include Logging
|
62
|
+
|
63
|
+
@@Info_Key = 'InfoKey: '
|
64
|
+
@@Info_Value = 'InfoValue: '
|
65
|
+
# instantiate an object of type CremeFraiche and define the
|
66
|
+
# versioning-information. Then does the rest... You need to
|
67
|
+
# provide the mail-files to a call of this method.
|
68
|
+
def initialize(*args)
|
69
|
+
init_logger($CONF.log_file ? $CONF.log_file : STDOUT, $CONF.log_level ? $CONF.log_level : Logger::UNKNOWN)
|
70
|
+
@app_name = 'Creme Fraiche'
|
71
|
+
@version = VERSION
|
72
|
+
@years = YEARS
|
73
|
+
@author = 'Michael Uplawski'
|
74
|
+
@author_mail = '<michael.uplawski@uplawski.eu>'
|
75
|
+
@file_path = __FILE__
|
76
|
+
@web_page = 'http://www.rubygems.org/gems/cremefraiche'
|
77
|
+
@msg = nil
|
78
|
+
@license = "This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version."
|
79
|
+
if RUBY_PLATFORM.include?('linux')
|
80
|
+
@cur_system = `uname -a`
|
81
|
+
else
|
82
|
+
@cur_system = RUBY_PLATFORM
|
83
|
+
end
|
84
|
+
@log.debug('args.flatten.empty? ' << args.flatten.empty?.to_s)
|
85
|
+
tfile = nil
|
86
|
+
if(args && args.flatten.empty? )
|
87
|
+
@log.debug('printing usage-message')
|
88
|
+
puts usage
|
89
|
+
elsif args[0] && 'user-conf' == args[0].chomp
|
90
|
+
@log.debug('handling user-configuration')
|
91
|
+
handle_user_conf
|
92
|
+
else
|
93
|
+
if args.length == 1 && args[0] == '-'
|
94
|
+
args.compact!
|
95
|
+
args.shift
|
96
|
+
# @log.debug('file piped-in: ' << $<.read)
|
97
|
+
# a file may be piped in from the command-line...
|
98
|
+
if(!$<.eof?)
|
99
|
+
# ... provide a temporary file in that case,
|
100
|
+
tfile = "%s/mail_message" %(Dir.pwd)
|
101
|
+
File.open(tfile, 'w+') {|of| of << $<.read}
|
102
|
+
@log.debug('Temporary eml-file is written.')
|
103
|
+
# ... then do as if it had been part of the argument-list.
|
104
|
+
args << tfile
|
105
|
+
# And I don't care. Really. Thanks.
|
106
|
+
end
|
107
|
+
end
|
108
|
+
@log.debug('processing ' << args.size.to_s << ' files')
|
109
|
+
# check_programs_installed
|
110
|
+
thr = BusyIndicator.new(true, 10)
|
111
|
+
args.each do |a|
|
112
|
+
num_files = 0
|
113
|
+
mailfile = EmlFile.new(a)
|
114
|
+
if(!mailfile.msg || mailfile.msg.empty?)
|
115
|
+
num_files = mailfile.files.size if mailfile.files
|
116
|
+
mailfile.mails do |m|
|
117
|
+
output = CFPrawn.new(m, File.dirname(a) )
|
118
|
+
# @msg = output.msg if output.msg
|
119
|
+
set_meta_data(output)
|
120
|
+
end
|
121
|
+
else
|
122
|
+
@msg = mailfile.msg
|
123
|
+
end
|
124
|
+
@log.info( trl("Processed %d eml-files") %num_files )
|
125
|
+
end
|
126
|
+
File.delete(tfile) if tfile && File.exist?(tfile)
|
127
|
+
thr.stop("done")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
133
|
+
# Should a user wish to either update her/his private version of the configuration-file by the current
|
134
|
+
# contents of the file originally found in the downloaded program package, this function does the job.
|
135
|
+
# It creates a copy of the original file, also, if there is not yet one, in ~/.cremefraiche/config or
|
136
|
+
# whatever the Configuration-singleton returns as file-name for user_configuration.
|
137
|
+
def handle_user_conf
|
138
|
+
conf_check = ConfCheck.new()
|
139
|
+
diffs = conf_check.diffs
|
140
|
+
replace = false
|
141
|
+
if( diffs)
|
142
|
+
if(diffs && diffs[:missing].empty? && diffs[:additional].empty?)
|
143
|
+
puts trl("No changes to your user-configuration are necessary.")
|
144
|
+
return false;
|
145
|
+
else
|
146
|
+
m = diffs[:missing]
|
147
|
+
a = diffs[:additional]
|
148
|
+
puts trl("\nThe following changes can be effectuated on your user-configuration")
|
149
|
+
puts "\t+ " << trl("New options") << ":\n\t\t" << m.join('\n\t\t ') if !m.empty?
|
150
|
+
puts "\t- " << trl("Obsolete Options") << ":\n\t\t" << a.join(', ') if !a.empty?
|
151
|
+
puts trl("Do you want to replace your current user-configuration?")
|
152
|
+
puts trl("If you answer 'yes' a back-up copy of your old file will still be available.")
|
153
|
+
puts trl("But your old settings will be replaced by the defaults.")
|
154
|
+
print trl("Your answer (Y/n): ")
|
155
|
+
replace = STDIN.getc.downcase == trl("y") ? true : false
|
156
|
+
end
|
157
|
+
if(! replace)
|
158
|
+
return false;
|
159
|
+
end
|
160
|
+
end
|
161
|
+
conf_check.write_user_conf
|
162
|
+
return replace;
|
163
|
+
end
|
164
|
+
=begin
|
165
|
+
# moved to configuration
|
166
|
+
|
167
|
+
# Finds external programs in the environment path.
|
168
|
+
# A decision to use one of those programs depends on the fact,
|
169
|
+
# that they are installed at all. Contradicting options will
|
170
|
+
# result in warning-messages in the protocol output.
|
171
|
+
def check_programs_installed
|
172
|
+
prog_names = %w"pdftk evince acroread okular gpdf"
|
173
|
+
$Progs = {} if !defined? $Progs
|
174
|
+
pathdirs = ENV['PATH'].split(File::PATH_SEPARATOR).collect do |d|
|
175
|
+
# BUGFIX: PATH may contain just anything!
|
176
|
+
pdir = nil
|
177
|
+
if(Dir.exist?(d) )
|
178
|
+
if(File.readable?(d) )
|
179
|
+
# create a non nil entry for pathdirs.
|
180
|
+
begin
|
181
|
+
pdir = Dir.new(d)
|
182
|
+
rescue Exception => ex
|
183
|
+
# "Trust nobody" (Herod V)
|
184
|
+
@log.error(trl("Cannot search for executables in %s") %d << ': ' << ex.message )
|
185
|
+
end
|
186
|
+
else
|
187
|
+
@log.warn(trl('The path-variable references an unreadable directory') << ': ' << d)
|
188
|
+
end
|
189
|
+
else
|
190
|
+
@log.warn(trl('The path-variable contains an invalid value') << ': ' << d)
|
191
|
+
end
|
192
|
+
# --------> Now this is neat...
|
193
|
+
pdir
|
194
|
+
end
|
195
|
+
# ... or wait ... It is not!
|
196
|
+
# Remove the nil-entries from pathdirs
|
197
|
+
pathdirs.compact!
|
198
|
+
# <------ Now this is neat...
|
199
|
+
|
200
|
+
if(pathdirs && !pathdirs.empty? )
|
201
|
+
@log.debug('path: ' + pathdirs.join(', ') )
|
202
|
+
exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : ['']
|
203
|
+
|
204
|
+
prog_names.each do |prog|
|
205
|
+
pathdirs.each do |dir|
|
206
|
+
exts.each do |ext|
|
207
|
+
# BUGFIX: Beware of case-variations in the
|
208
|
+
# defined program-extension. Windows-specific.
|
209
|
+
# Thanks to Tijn Gommans for pointing this out.
|
210
|
+
$Progs[prog] |= dir.entries.include?("#{prog}#{ext.upcase}")
|
211
|
+
$Progs[prog] |= dir.entries.include?("#{prog}#{ext.downcase}")
|
212
|
+
|
213
|
+
end
|
214
|
+
end
|
215
|
+
end
|
216
|
+
end
|
217
|
+
@log.debug("found the following external programs: " << $Progs.to_s)
|
218
|
+
end
|
219
|
+
=end
|
220
|
+
# Using PDFTK, this method will alter the values of some
|
221
|
+
# meta-data fields in the resulting pdf-file.
|
222
|
+
def set_meta_data(cfprawn)
|
223
|
+
if($Progs['pdftk'] )
|
224
|
+
encoding = 'iso-8859-1'
|
225
|
+
cf = 'Crème Fraiche'
|
226
|
+
|
227
|
+
pdf = cfprawn.outfile
|
228
|
+
headers = cfprawn.headers
|
229
|
+
t_file = "%s/temp_pdf" %[$CONF.temp_dir.path]
|
230
|
+
info_file = "%s/cr_info" %[$CONF.temp_dir.path]
|
231
|
+
@log.debug('temp_dir path is ' << $CONF.temp_dir.path)
|
232
|
+
meta_fields = %w"Author Subject Keywords Title"
|
233
|
+
meta_data = {'Creator' => cf, 'Producer' => cf}
|
234
|
+
meta_fields.each do |f|
|
235
|
+
v = $CONF.send(f)
|
236
|
+
meta_data[f] = v if v && !v.empty?
|
237
|
+
end
|
238
|
+
if(!meta_data['Subject'] )
|
239
|
+
subject_header = headers.detect {|h| h.name == 'Subject'}
|
240
|
+
meta_data['Subject'] = subject_header.value if subject_header
|
241
|
+
end
|
242
|
+
@log.debug('meta_data is ' << meta_data.inspect)
|
243
|
+
begin
|
244
|
+
File.open(info_file, 'w+') do |info|
|
245
|
+
meta_data.each_pair do |k, v|
|
246
|
+
info << @@Info_Key << k << "\n"
|
247
|
+
info << @@Info_Value << v.encode(encoding) << "\n\n"
|
248
|
+
end
|
249
|
+
end
|
250
|
+
rescue Exception =>ex
|
251
|
+
@log.warn('PDFTK: ' << trl("Cannot write meta-data to temporary info-file (%s)" %ex.message))
|
252
|
+
end
|
253
|
+
cmd = Escape.shell_command(["pdftk", pdf, "update_info", info_file, "output", t_file]).to_s
|
254
|
+
@log.debug('pdftk-command is ' << cmd)
|
255
|
+
begin
|
256
|
+
puts("\n" << trl("-----> The following output is created by pdftk. A PDF-file has already been created. <-----") )
|
257
|
+
pdftk_result = system( cmd)
|
258
|
+
puts("\n" << trl("<--------------------- End of pdftk output ------------------------------------------------>") )
|
259
|
+
@log.debug('pdftk_result is: ' << pdftk_result.to_s)
|
260
|
+
begin
|
261
|
+
FileUtils.mv(t_file, pdf)
|
262
|
+
rescue Exception => ex
|
263
|
+
@log.warn(trl("Cannot replace the pdf-file by a new version (%s)") %ex.message)
|
264
|
+
end
|
265
|
+
rescue Exception => ex
|
266
|
+
@log.warn('PDFTK: ' << trl("Error upon execution of the command '%s': %s") %[cmd, ex.message] )
|
267
|
+
end
|
268
|
+
else
|
269
|
+
@log.warn(trl('Metadata could not be written, pdftf is apparently not installed.'))
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
# Currently unused. Kept for reference.
|
274
|
+
def result_message(results)
|
275
|
+
width = results.keys.any? ? results.keys.max {|a, b| a.length <=>b.length }.length : 0
|
276
|
+
results.keys.each_with_index do |k, i|
|
277
|
+
puts "%i.) %#{width}s => %s" %[i+1, k, results[k] ? results[k] : trl("ERROR")]
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# creates and prints the usage-message
|
282
|
+
def self.usage
|
283
|
+
CremeFraiche.new.usage
|
284
|
+
end
|
285
|
+
|
286
|
+
# Combines and returns a hash with information on
|
287
|
+
# the program and the system it is running on.
|
288
|
+
def self.prog_info
|
289
|
+
cf = CremeFraiche.new
|
290
|
+
p_info = {:cur_system => cf.cur_system, :web_page => cf.web_page, :app_name => cf.app_name, :version => cf.version, :years => cf.years, :author => cf.author, :author_mail => cf.author_mail }
|
291
|
+
end
|
292
|
+
|
293
|
+
# prints the usage message
|
294
|
+
def usage
|
295
|
+
if $WIN
|
296
|
+
system 'cls'
|
297
|
+
else
|
298
|
+
system( 'clear')
|
299
|
+
end
|
300
|
+
prog_version = (@app_name.dup << ' ' << trl("version %s") %[@version])
|
301
|
+
sub_title = trl('EML to PDF converter')
|
302
|
+
width = 32 + [prog_version, sub_title].max {|a, b| a.length <=>b.length}.length
|
303
|
+
hr = '━' * width
|
304
|
+
|
305
|
+
ustr = []
|
306
|
+
ustr << " ┏%s┓" %hr
|
307
|
+
ustr << " ┃%#{width - 16}s ┃" %prog_version
|
308
|
+
ustr << " ┃%#{width - 16}s ┃" %sub_title
|
309
|
+
ustr << " ┗%s┛" %hr
|
310
|
+
ustr << ''
|
311
|
+
ustr << " © %s %s %s" %[@years, @author, @author_mail]
|
312
|
+
ustr << ''
|
313
|
+
ustr << " %s" %(trl("Running with Ruby %s on %s") %[RUBY_VERSION, RUBY_PLATFORM])
|
314
|
+
ustr << ''
|
315
|
+
u = trl("Usage")
|
316
|
+
ulen = u.length + 1;
|
317
|
+
ustr << " %s:" %u
|
318
|
+
ustr << ('▔' * ulen )
|
319
|
+
ustr << " \tuser@machine:~$ cremefraiche [%s.eml] <%s.eml ... %s(n).eml>" %[trl('eml_file1'), trl('eml_file2'), trl('eml_file')]
|
320
|
+
ustr << ''
|
321
|
+
ustr << " %s" %trl('This produces 1 PDF-file for each individual email found in the given eml-file(s).')
|
322
|
+
ustr << " %s:" %trl("Please see the file 'config' in the program- or gem-folder for some options")
|
323
|
+
ustr << " \t%s" %[$CONF.config_file]
|
324
|
+
ustr << ''
|
325
|
+
ustr << " %s:" %trl("To create or update a user-version of the configuration-file")
|
326
|
+
ustr << ('▔' * ulen )
|
327
|
+
ustr << " \tuser@machine:~$ ruby cremefraiche user-conf"
|
328
|
+
ustr << ''
|
329
|
+
ustr << " %s %s" %[trl("Use literally 'user-conf' as argument."), trl("This either creates or overwrites a configuration file in a sub-directory '.cremefraiche' of the current user's home-directory")]
|
330
|
+
ustr << "\n"
|
331
|
+
ustr << "This program is free software under the terms of the GNU General Public License"
|
332
|
+
ustr << "version 3 or any later version. It is provided as is with no guarantees of any kind."
|
333
|
+
ustr << "\n" * 2
|
334
|
+
ustr.join("\n")
|
335
|
+
end
|
336
|
+
public
|
337
|
+
attr_reader :output, :web_page, :cur_system, :app_name, :version, :author, :years, :author_mail, :msg
|
338
|
+
end
|
339
|
+
|
340
|
+
# CremeFraiche.new(*ARGV)
|
341
|
+
|