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
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 48cc0065d28074c113f879f7dbc47e424b78a52e75f54eeb74f25d287658e8c6
|
4
|
+
data.tar.gz: 16b22c86a2c3843de9a3000c336108196bb2deb480eaff8761f8d22b2cb07075
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 6a668022a9d83c0977c6f53fd0b8ab19cb9ebfb5b74ddc8d3203862ce7daf369a28b7abc55259dcde290f7224cbba4f1edc1ce4a4b6d8ff4680aee646d824830
|
7
|
+
data.tar.gz: ee181963d9fbf566b13a40777c78295d01503d449145746a64a76bdb10d1050e96d2d4e39ba0db8622b4c54a97a1c6b969c03491d005d5829f14b69790406b8a
|
data/README.md
ADDED
@@ -0,0 +1,114 @@
|
|
1
|
+
Creme Fraîche
|
2
|
+
=======================
|
3
|
+
Email to PDF Konverter
|
4
|
+
------------------------------------------
|
5
|
+
|
6
|
+
SYNOPSIS
|
7
|
+
=======================
|
8
|
+
|
9
|
+
**cremefraiche [eml-files] ...**
|
10
|
+
|
11
|
+
**cremefraiche < mail**
|
12
|
+
|
13
|
+
**cremefraicheGui**
|
14
|
+
|
15
|
+
|
16
|
+
|
17
|
+
DESCRIPTION
|
18
|
+
=======================
|
19
|
+
This program converts email to PDF. The objective is to keep readable
|
20
|
+
versions of the messages, HTML versions of the processed mails are simplified,
|
21
|
+
colors and images are lost in the process.
|
22
|
+
|
23
|
+
The resulting mails will be created either
|
24
|
+
|
25
|
+
* in the same directory alongside the original eml files
|
26
|
+
|
27
|
+
* when 1 mail is piped-in to cremefraiche, in the *current working directory*.
|
28
|
+
In this case, the new PDF-file will overwrite, if it exists, an existing file
|
29
|
+
*001_mail_message.pdf*
|
30
|
+
|
31
|
+
**ATTN!** Not all html flavors will result in usable PDF; reacting to all
|
32
|
+
possible variations in the way that Mail is created these days, is an ongoing
|
33
|
+
endeavor. If you need authentic output of a HTML mail, **use a different
|
34
|
+
software**, a Web Browser or a converter specifically developed for the task.
|
35
|
+
|
36
|
+
CONFIGURATION
|
37
|
+
===============
|
38
|
+
Cremefraiche is highly configurable.
|
39
|
+
|
40
|
+
To create your own version of the configuration file in order to modify
|
41
|
+
the behavior of the program, execute cremefraiche once with the only
|
42
|
+
argument “user-conf”:
|
43
|
+
|
44
|
+
**user@machine:~$ cremefraiche user-conf**
|
45
|
+
|
46
|
+
The file will be written in a hidden subdirectory *.cremefraiche* and is
|
47
|
+
named *config*. It is full of explanations and it should be no problem to do the
|
48
|
+
necessary adaptations directly in the file.
|
49
|
+
|
50
|
+
You can also set and modify values in the GUI, after pushing the button
|
51
|
+
that refers to the configuration.
|
52
|
+
|
53
|
+
The Graphical User Interface
|
54
|
+
============================
|
55
|
+
Execute
|
56
|
+
|
57
|
+
**cremefraicheGui**.
|
58
|
+
|
59
|
+
The simplistic GUI serves to keep a list of eml files for repeated conversion
|
60
|
+
to PDF. You can also exempt files from this list from an immediate conversion
|
61
|
+
but keep it for later use.
|
62
|
+
|
63
|
+
In the GUI, you can also decide to interrupt running conversions in a
|
64
|
+
way that necessitates a kill-signal in the console version of the program.
|
65
|
+
|
66
|
+
Other Information
|
67
|
+
=================
|
68
|
+
|
69
|
+
pipe-in a mail from STDIN
|
70
|
+
--------------------------
|
71
|
+
You can pipe in mails to cremefraiche. This is useful for use in conjunction
|
72
|
+
with mail-clients that allow such operation, notably the *Mutt* mail client.
|
73
|
+
For Mutt, it is sufficient to define two macros in the file .muttrc :
|
74
|
+
|
75
|
+
<code>macro index X "|cremefraiche -\n" "make PDF"</code>
|
76
|
+
|
77
|
+
<code>macro pager X "|cremefraiche -\n" "make PDF"</code>
|
78
|
+
|
79
|
+
This will enable the Shortcut *Shift-x* in the mail index and in the pager.
|
80
|
+
|
81
|
+
Source-Code
|
82
|
+
-----------
|
83
|
+
The gem-file that you get with the gem-utility or from rubygems.org contains
|
84
|
+
all the code of the program and some documentation (this page notably). To read
|
85
|
+
its content, you must
|
86
|
+
|
87
|
+
1. untar the gem-file with tar _-xf cremefraiche-1.1.7.gem_
|
88
|
+
2. uncompress the data.gz archive: _gunzip data.gz_
|
89
|
+
3. untar the resultig data.tar archive: _tar -xf data.tar_
|
90
|
+
|
91
|
+
This creates the directories bin, doc and lib.
|
92
|
+
|
93
|
+
Why « Crème Fraîche » ?
|
94
|
+
-----------------------
|
95
|
+
As with *Crème Fraîche* you create splendid meals from otherwise frugal
|
96
|
+
ingredients, I found it a good name for the initial versions of the program.
|
97
|
+
|
98
|
+
In the meantime – and under the influence of too much HTML garbage – I wonder
|
99
|
+
what you will make of it. Though simplifying the HTML-mail that I receive, in
|
100
|
+
an effort to make it readable, is still an objective.
|
101
|
+
|
102
|
+
License
|
103
|
+
-------
|
104
|
+
**Cremefraiche** is distributed under the conditions of the WTFPL-2.0 or later
|
105
|
+
License (see http://www.wtfpl.net/txt/copying/ or license-text in the doc
|
106
|
+
directory of the gem-file).
|
107
|
+
|
108
|
+
Author
|
109
|
+
-----
|
110
|
+
Cremefraiche has been developed by
|
111
|
+
Michael Uplawski <michael.uplawski@uplawski.eu>
|
112
|
+
|
113
|
+
Ω
|
114
|
+
==
|
data/bin/cremefraiche
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#encoding: UTF-8
|
3
|
+
=begin
|
4
|
+
/***************************************************************************
|
5
|
+
* ©2011-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
|
+
$WIN = (RUBY_PLATFORM =~ /mswin/)
|
19
|
+
|
20
|
+
require_relative '../lib/translating'
|
21
|
+
require_relative '../lib/basic_logging'
|
22
|
+
require_relative '../lib/cremefraiche'
|
23
|
+
require_relative '../lib/confcheck'
|
24
|
+
require_relative '../lib/version'
|
25
|
+
|
26
|
+
extend(BasicLogging)
|
27
|
+
extend(Translating)
|
28
|
+
|
29
|
+
# prints the usage message
|
30
|
+
def usage
|
31
|
+
if $WIN
|
32
|
+
system 'cls'
|
33
|
+
else
|
34
|
+
system( 'clear')
|
35
|
+
end
|
36
|
+
prog_version = (App_name.dup << ' ' << trl("version %s") %[VERSION])
|
37
|
+
sub_title = trl('EML to PDF converter')
|
38
|
+
width = 32 + [prog_version, sub_title].max {|a, b| a.length <=>b.length}.length
|
39
|
+
hr = '━' * width
|
40
|
+
|
41
|
+
ustr = []
|
42
|
+
ustr << " ┏%s┓" %hr
|
43
|
+
ustr << " ┃%#{width - 16}s ┃" %prog_version
|
44
|
+
ustr << " ┃%#{width - 16}s ┃" %sub_title
|
45
|
+
ustr << " ┗%s┛" %hr
|
46
|
+
ustr << ''
|
47
|
+
ustr << " © %s %s %s" %[YEARS, Author, Author_mail]
|
48
|
+
ustr << ''
|
49
|
+
ustr << " %s" %(trl("Running with Ruby %s on %s") %[RUBY_VERSION, RUBY_PLATFORM])
|
50
|
+
ustr << ''
|
51
|
+
u = trl("Usage")
|
52
|
+
ulen = u.length + 1;
|
53
|
+
ustr << " %s:" %u
|
54
|
+
ustr << ('▔' * ulen )
|
55
|
+
ustr << " \tuser@machine:~$ cremefraiche [%s.eml] <%s.eml ... %s(n).eml>" %[trl('eml_file1'), trl('eml_file2'), trl('eml_file')]
|
56
|
+
ustr << ''
|
57
|
+
ustr << " %s" %trl('This produces 1 PDF-file for each individual email found in the given eml-file(s).')
|
58
|
+
ustr << " %s:" %trl("Please see the file 'config' in the program- or gem-folder for some options")
|
59
|
+
ustr << " \t%s" %[$CONF.config_file]
|
60
|
+
ustr << ''
|
61
|
+
ustr << " %s:" %trl("To create or update a user-version of the configuration-file")
|
62
|
+
ustr << ('▔' * ulen )
|
63
|
+
ustr << " \tuser@machine:~$ ruby cremefraiche user-conf"
|
64
|
+
ustr << ''
|
65
|
+
ustr << " %s %s" %[trl("Use literally 'user-conf' as argument."), trl("This either creates or overwrites\n a configuration file in a sub-directory '.cremefraiche' of the current user's home-directory")]
|
66
|
+
ustr << "\n"
|
67
|
+
ustr << "This program is free software under the terms of the WTFPL version 2 or later. "
|
68
|
+
ustr << "It is provided as is with no guarantees of any kind."
|
69
|
+
ustr << "\n" * 2
|
70
|
+
ustr.join("\n")
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
|
75
|
+
if(ARGV && ARGV.flatten.empty? )
|
76
|
+
debug('printing usage-message')
|
77
|
+
puts usage()
|
78
|
+
elsif ARGV[0] && 'user-conf' == ARGV[0].chomp
|
79
|
+
debug('handling user-configuration')
|
80
|
+
handle_user_conf
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
cf = CremeFraiche.instance()
|
85
|
+
cf.process(*ARGV)
|
86
|
+
|
87
|
+
# Should a user wish to either update her/his private version of the configuration-file by the current
|
88
|
+
# contents of the file originally found in the downloaded program package, this function does the job.
|
89
|
+
# It creates a copy of the original file, also, if there is not yet one, in ~/.cremefraiche/config or
|
90
|
+
# whatever the Configuration-singleton returns as file-name for user_configuration.
|
91
|
+
def handle_user_conf
|
92
|
+
conf_check = ConfCheck.new()
|
93
|
+
diffs = conf_check.diffs
|
94
|
+
replace = false
|
95
|
+
if( diffs)
|
96
|
+
if(diffs && diffs[:missing].empty? && diffs[:additional].empty?)
|
97
|
+
puts trl("No changes to your user-configuration are necessary.")
|
98
|
+
return false;
|
99
|
+
else
|
100
|
+
m = diffs[:missing]
|
101
|
+
a = diffs[:additional]
|
102
|
+
puts trl("\nThe following changes can be effectuated on your user-configuration")
|
103
|
+
puts "\t+ " << trl("New options") << ":\n\t\t" << m.join('\n\t\t ') if !m.empty?
|
104
|
+
puts "\t- " << trl("Obsolete Options") << ":\n\t\t" << a.join(', ') if !a.empty?
|
105
|
+
puts trl("Do you want to replace your current user-configuration?")
|
106
|
+
puts trl("If you answer 'yes' a back-up copy of your old file will still be available.")
|
107
|
+
puts trl("But your old settings will be replaced by the defaults.")
|
108
|
+
print trl("Your answer (Y/n): ")
|
109
|
+
replace = STDIN.getc.downcase == trl("y") ? true : false
|
110
|
+
end
|
111
|
+
if(! replace)
|
112
|
+
return false;
|
113
|
+
end
|
114
|
+
end
|
115
|
+
conf_check.write_user_conf
|
116
|
+
return replace;
|
117
|
+
end
|
data/bin/cremefraicheGui
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
#encoding: UTF-8
|
3
|
+
=begin
|
4
|
+
/***************************************************************************
|
5
|
+
* ©2011-2013, 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
|
+
|
23
|
+
|
24
|
+
=end
|
25
|
+
require_relative '../lib/gui/cremefraicheGui'
|
26
|
+
CremeFraicheGui.new(ARGV)
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require_relative "lib/version"
|
2
|
+
require 'date'
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.version = VERSION
|
6
|
+
s.name = File.basename(__FILE__, '.gemspec')
|
7
|
+
s.date = Date.today.strftime('%F')
|
8
|
+
s.summary = SUMMARY
|
9
|
+
s.description = "transforms EML files to PDF"
|
10
|
+
s.authors = Author
|
11
|
+
s.email = Author_mail
|
12
|
+
s.files = Dir.children('doc').collect{|f| 'doc/' << File::path(f)} + Dir.children('bin').collect{|f| 'bin/' << File::path(f)} + Dir.children('lib').collect{|f| 'lib/' << File::path(f) } + Dir.children('lib/gui/').collect{|f| 'lib/gui/' << File::path(f) } + Dir.children('lib/icon').collect{|f| 'lib/icon/' << File::path(f) } + Dir.children('lib/busy_indicator').collect{|f| 'lib/busy_indicator/' << File::path(f) } + %w~cremefraiche.gemspec~.collect{|f|f} << "README.md"
|
13
|
+
s.homepage = ''
|
14
|
+
s.requirements = 'prawn prawn-table escape nokogiri mail gtk3'
|
15
|
+
s.add_runtime_dependency 'prawn', '~> 2.4', '>= 2.4.0'
|
16
|
+
s.add_runtime_dependency 'prawn-table', '~> 0.2', '>= 0.2.2'
|
17
|
+
s.add_runtime_dependency 'escape', '~> 0.0', '>= 0.0.4'
|
18
|
+
s.add_runtime_dependency 'nokogiri', '~> 1.13', '>= 1.13.10'
|
19
|
+
s.add_runtime_dependency 'mail', '~> 2.8', '>= 2.8.0'
|
20
|
+
s.add_runtime_dependency 'gtk3', '~> 4.0', '>= 4.0.5'
|
21
|
+
s.executables = 'cremefraiche', 'cremefraicheGui'
|
22
|
+
s.license = 'GPL-3.0'
|
23
|
+
s.required_ruby_version = '>= 2.5'
|
24
|
+
end
|
data/doc/gui_howto.pdf
ADDED
Binary file
|
data/lib/LANG
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
en
|
@@ -0,0 +1,170 @@
|
|
1
|
+
#!/bin/env ruby
|
2
|
+
#encoding: UTF-8
|
3
|
+
=begin
|
4
|
+
/***************************************************************************
|
5
|
+
* ©2013-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, see *
|
9
|
+
* http://www.wtfpl.net/about/ *
|
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
|
+
#
|
19
|
+
# Simplified logging.
|
20
|
+
# See example code at the bottom of this file.
|
21
|
+
# Execute this file to see the output.
|
22
|
+
#
|
23
|
+
|
24
|
+
#require 'time'
|
25
|
+
|
26
|
+
module BasicLogging
|
27
|
+
|
28
|
+
DEBUG = 0
|
29
|
+
INFO = 1
|
30
|
+
WARN = 2
|
31
|
+
ERROR = 3
|
32
|
+
FATAL = 4
|
33
|
+
UNKNOWN = nil
|
34
|
+
|
35
|
+
# this is mainly for the translation of method calls into log levels
|
36
|
+
Levels = {:debug => DEBUG, :info => INFO, :warn => WARN, :error => ERROR,
|
37
|
+
:fatal => FATAL, :unknown => UNKNOWN}
|
38
|
+
|
39
|
+
@@log_level = UNKNOWN
|
40
|
+
@@target = STDOUT
|
41
|
+
@@muted = []
|
42
|
+
|
43
|
+
# do not log, if caller is name (class or instance)
|
44
|
+
def self.mute(obj)
|
45
|
+
name = obj.class == Class ? obj.name.dup : obj.class.name
|
46
|
+
@@muted << name
|
47
|
+
end
|
48
|
+
|
49
|
+
def self.is_muted?(obj)
|
50
|
+
name = obj.class == Class ? obj.name.dup : obj.class.name
|
51
|
+
@@muted.include?(name)
|
52
|
+
end
|
53
|
+
|
54
|
+
# set the log level for the calling class or object
|
55
|
+
def set_level(lv)
|
56
|
+
if lv.respond_to?(:to_str)
|
57
|
+
lv = Levels[lv.to_sym]
|
58
|
+
end
|
59
|
+
if(!lv || (lv.respond_to?(:to_int) && lv >= DEBUG && lv <= FATAL) )
|
60
|
+
@@log_level = lv
|
61
|
+
else
|
62
|
+
STDERR.puts __FILE__.dup << ": ERROR : invalid log level \"" << lv.to_s << "\""
|
63
|
+
STDERR.puts "Keepinng old log level " << Levels.keys.detect {| k| Levels[k] == @@log_level}.to_s
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# set the log target for the calling class or object
|
68
|
+
def set_target(tg)
|
69
|
+
if tg.respond_to?(:to_io)
|
70
|
+
@@target = tg
|
71
|
+
elsif(!File::exist?(tg) || ( File.file?(tg) && File.writable?(tg) ) )
|
72
|
+
@@target = File.open(tg, 'w+')
|
73
|
+
else
|
74
|
+
STDERR.puts __FILE__.dup << ': ERROR : target ' << tg << ' cannot be set'
|
75
|
+
STDERR.puts "Keeping old target " << @@target.inspect
|
76
|
+
return
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
# Output of log messages, depending on the log level set for the calling class
|
81
|
+
# and the name of the alias method which is actually called.
|
82
|
+
def log(message)
|
83
|
+
if !BasicLogging.is_muted?(self)
|
84
|
+
# how has this method been called?
|
85
|
+
mlevel = __callee__
|
86
|
+
if Levels.has_key?(mlevel) && Levels[mlevel] <= FATAL
|
87
|
+
# output only for levels equal or above the value that corresponds to
|
88
|
+
# the calling alias.
|
89
|
+
format_log( message, mlevel) if @@log_level && Levels[mlevel] >= @@log_level
|
90
|
+
else
|
91
|
+
STDERR.puts __FILE__.dup << ": ERROR : invalid log level \"" << mlevel.to_s << "\""
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
alias :debug :log
|
97
|
+
alias :info :log
|
98
|
+
alias :warn :log
|
99
|
+
alias :error :log
|
100
|
+
alias :fatal :log
|
101
|
+
|
102
|
+
attr_reader :target, :log_level
|
103
|
+
|
104
|
+
private
|
105
|
+
|
106
|
+
# 1 format_log for all loggers.
|
107
|
+
def format_log(message, mlevel)
|
108
|
+
# indicate if a registered class or the registered object of a class is calling.
|
109
|
+
name = self.class == Class ? self.name.dup << ' [class]' : self.class.name
|
110
|
+
@@target.puts '' << name << ' ' << mlevel.to_s << ' ' << Time.now.strftime("%H:%M:%S:%6N") << ': ' << message
|
111
|
+
end
|
112
|
+
end
|
113
|
+
#---------test: execute file----------
|
114
|
+
if $0 == __FILE__
|
115
|
+
Array.extend(BasicLogging)
|
116
|
+
Array.set_level(BasicLogging::INFO)
|
117
|
+
Array.info('TEST')
|
118
|
+
ar = Array.new
|
119
|
+
ar.extend(BasicLogging)
|
120
|
+
# --- no output :
|
121
|
+
l = __LINE__
|
122
|
+
ar.debug(l.next.to_s << ': debug-test 0')
|
123
|
+
# output
|
124
|
+
ar.set_level(BasicLogging::DEBUG)
|
125
|
+
l = __LINE__
|
126
|
+
ar.debug(l.next.to_s << ': debug-test 1')
|
127
|
+
|
128
|
+
obj = Object.new
|
129
|
+
obj.extend(BasicLogging)
|
130
|
+
obj.set_level(BasicLogging::DEBUG)
|
131
|
+
puts "--------debug-----------"
|
132
|
+
obj.debug('debug')
|
133
|
+
obj.info('info')
|
134
|
+
obj.warn('warn')
|
135
|
+
obj.error('error')
|
136
|
+
obj.fatal('fatal')
|
137
|
+
puts "--------info-----------"
|
138
|
+
obj.set_level("info")
|
139
|
+
obj.debug('debug')
|
140
|
+
obj.info('info')
|
141
|
+
obj.warn('warn')
|
142
|
+
obj.error('error')
|
143
|
+
obj.fatal('fatal')
|
144
|
+
puts "--------fatal-----------"
|
145
|
+
obj.set_level("fatal")
|
146
|
+
obj.debug('debug')
|
147
|
+
obj.info('info')
|
148
|
+
obj.warn('warn')
|
149
|
+
obj.error('error')
|
150
|
+
obj.fatal('fatal')
|
151
|
+
puts "--------UNKNOWN-----------"
|
152
|
+
obj.set_level(nil)
|
153
|
+
obj.debug('debug')
|
154
|
+
obj.info('info')
|
155
|
+
obj.warn('warn')
|
156
|
+
obj.error('error')
|
157
|
+
obj.fatal('fatal')
|
158
|
+
puts " ------ Output into file ----"
|
159
|
+
obj.set_target "/tmp/test_log.log"
|
160
|
+
puts " ------ INFO -----------"
|
161
|
+
obj.set_level BasicLogging::INFO
|
162
|
+
obj.info('info output')
|
163
|
+
|
164
|
+
obj.info('info output 2')
|
165
|
+
puts "---------- invalid -------"
|
166
|
+
obj.set_target "/dev/sr0"
|
167
|
+
obj.set_level "power"
|
168
|
+
end
|
169
|
+
|
170
|
+
# EOF
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,50 @@
|
|
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
|
+
|
16
|
+
A test and demo for the BusyIndicator.
|
17
|
+
This does not use the final BusyIndicator but directly creates
|
18
|
+
a Thread.
|
19
|
+
=end
|
20
|
+
require './color_output'
|
21
|
+
|
22
|
+
def clean_busy_indicator(thr, width, comment)
|
23
|
+
thr.terminate
|
24
|
+
thr.join
|
25
|
+
print ("\b" * width)
|
26
|
+
print ("%+#{width}s\n" %comment)
|
27
|
+
end
|
28
|
+
|
29
|
+
def busy_indicator(width)
|
30
|
+
tobj = Thread.new() do
|
31
|
+
loop do
|
32
|
+
%w"OOO ooo ___ ooo".each do |s|
|
33
|
+
print "%+#{width}s" %s
|
34
|
+
sleep 0.1
|
35
|
+
print ("\b" * width)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
# =======================
|
41
|
+
if($0 == __FILE__)
|
42
|
+
width = 20
|
43
|
+
2.times do
|
44
|
+
puts "I am busy, pse wait..."
|
45
|
+
thr = busy_indicator(width)
|
46
|
+
sleep 3
|
47
|
+
clean_busy_indicator(thr, width, "Okay")
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,89 @@
|
|
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 'color_output'
|
18
|
+
|
19
|
+
#The BusyIndicator will show an "Animation" for the time of its execution.
|
20
|
+
#The main program will continue to run in its own thread and should stop
|
21
|
+
#the BusyIndicator, once that a process of longer duration has terminated.
|
22
|
+
class BusyIndicator
|
23
|
+
attr_writer :width
|
24
|
+
# Defines a busy_indicator of a width of 'width' characters.
|
25
|
+
# If 'start' is true, the text-animation is run immediately.
|
26
|
+
def initialize(start = true, width = nil)
|
27
|
+
@width = width && width >= 3 ? width : 3
|
28
|
+
@thr = busy_indicator(@width) if start
|
29
|
+
end
|
30
|
+
|
31
|
+
# Starts the text-animation, returns the thread.
|
32
|
+
def run()
|
33
|
+
@thr = busy_indicator(@width)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Stops the text-animation, terminates the thread.
|
37
|
+
# If comment is not null, it will be displayed in the end.
|
38
|
+
def stop(comment)
|
39
|
+
@thr.terminate
|
40
|
+
@thr.join
|
41
|
+
print ("\b" * @width)
|
42
|
+
print ("%+#{@width}s\n" %comment)
|
43
|
+
end
|
44
|
+
private
|
45
|
+
def busy_indicator(width)
|
46
|
+
tobj = Thread.new() do
|
47
|
+
print "working ... "
|
48
|
+
loop do
|
49
|
+
# %w"OOO ooo ___ ooo".each do |s|
|
50
|
+
%w"000 OOO UUU VVV YYY TTT 777 >>> === --- ooo".each do |s|
|
51
|
+
# %w"0OU OUV UVY VYT YT7 T7> 7>= >=- =-o -o0 o0O".each do |s|
|
52
|
+
print "%+#{width}s" %s
|
53
|
+
sleep 0.1
|
54
|
+
print ("\b" * width)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
# =======================
|
61
|
+
# Example
|
62
|
+
# You can run this file directly from a command-line,
|
63
|
+
# like this
|
64
|
+
# user@mchine$: ruby busy_indicator.rb
|
65
|
+
#
|
66
|
+
# The program below will then start four (4)
|
67
|
+
# BusyIndicators and stop them again, one by one.
|
68
|
+
# The width of the "animation" is variated.
|
69
|
+
# In the loop, the BusyIndicator is started upon
|
70
|
+
# its creation, the other two instances are first
|
71
|
+
# created then 'run'.
|
72
|
+
if($0 == __FILE__)
|
73
|
+
width = 20
|
74
|
+
2.times do
|
75
|
+
puts "I am busy, pse wait..."
|
76
|
+
thr = BusyIndicator.new(true, width)
|
77
|
+
sleep 3
|
78
|
+
thr.stop("Okay")
|
79
|
+
end
|
80
|
+
bi = BusyIndicator.new(false)
|
81
|
+
bi.run
|
82
|
+
sleep 3
|
83
|
+
bi.stop("Stopped")
|
84
|
+
bi.width = 8
|
85
|
+
bi.run
|
86
|
+
sleep 3
|
87
|
+
bi.stop("stopped again")
|
88
|
+
end
|
89
|
+
|
@@ -0,0 +1,45 @@
|
|
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
|
+
# Helper functions for color-output to an Ansi-terminal.
|
18
|
+
# ... I have never seen an Ansi-terminal, but learned that about each Linux
|
19
|
+
# terminal-emulator can behave like one.
|
20
|
+
# And anyway. This works.
|
21
|
+
|
22
|
+
COLORS = {:default => 9, :black => 0, :red => 1, :green => 2, :yellow => 3, :blue => 4, :purple => 5, :cyan => 6, :white => 7 }
|
23
|
+
|
24
|
+
BG = 4
|
25
|
+
FG = 3
|
26
|
+
REGULAR = 0
|
27
|
+
BOLD = 1
|
28
|
+
UNDERLINE = 4
|
29
|
+
BLINK = 5
|
30
|
+
SWAP = 7
|
31
|
+
NEUTRAL = 0
|
32
|
+
|
33
|
+
STYLES = {:regular => REGULAR, :bold => BOLD, :underline => UNDERLINE, :blink => BLINK, :swap => SWAP, :neutral => NEUTRAL}
|
34
|
+
|
35
|
+
def colored_text(text, color_code)
|
36
|
+
"#{color_code}#{text}e[0m"
|
37
|
+
end
|
38
|
+
|
39
|
+
def colored_output(output_text, fg_color = :default, bg_color = :default, style = :regular , mode = :neutral )
|
40
|
+
"\033[%i;%i;%i%i;%i%im%s\033[0m" %[STYLES[mode.to_sym], STYLES[style.to_sym], FG, COLORS[fg_color.to_sym], BG, COLORS[bg_color.to_sym], output_text]
|
41
|
+
end
|
42
|
+
|
43
|
+
def red(text); colorize(text, "\033[31m"); end
|
44
|
+
def green(text); colorize(text, "\033[32m"); end
|
45
|
+
|