maillinks 0.2.1 → 1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/maillinks +1 -1
- data/changes.txt +11 -0
- data/doc/html/maillinks.html +23 -6
- data/doc/man/maillinks.1.gz +0 -0
- data/doc/pdf/maillinks.pdf +0 -0
- data/doc/rst/maillinks.rst +20 -6
- data/lib/basic_logging.rb +60 -12
- data/lib/color_output.rb +41 -4
- data/lib/maillinks.rb +43 -18
- data/maillinks.gemspec +4 -3
- metadata +6 -5
- data/lib/file_checking.rb +0 -81
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 89761f37cdcbd81624099ee4c33be1ca947d1d1b9e35e163d3f1fc9b7a5352e6
|
|
4
|
+
data.tar.gz: 9bf6e5064d6d0f9a133412a742dd0e45956237d9a4e201dd0e9b4bdaaa817b45
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 3dfc53ff1e68fd36baf64993c88fcb7d37e36f0471d773ba5667cee77e9bb2f29934e8c74ce33bf3db770af8a8e5d7884d65e9b9f867b5ca254b10084ff82fba
|
|
7
|
+
data.tar.gz: a96b8bbf909b84fc864770db81b819c05a0222979b57fd68ef486fe411a1637553e02611d4df867db09ba50ea4e1e4824d48d1eab532ad46caeb5219c1e02f10
|
data/bin/maillinks
CHANGED
|
@@ -20,12 +20,12 @@ self.extend BasicLogging
|
|
|
20
20
|
|
|
21
21
|
if ARGV.length > 1 && BasicLogging::Levels.keys.include?(ARGV[1].strip.downcase.to_sym )
|
|
22
22
|
$LOG_LEVEL = ARGV[1].strip.downcase.to_sym
|
|
23
|
-
debug 'log level will be ' << $LOG_LEVEL.to_s
|
|
24
23
|
else
|
|
25
24
|
$LOG_LEVEL = :info
|
|
26
25
|
end
|
|
27
26
|
|
|
28
27
|
set_level($LOG_LEVEL)
|
|
28
|
+
debug 'log level will be ' << $LOG_LEVEL.to_s
|
|
29
29
|
|
|
30
30
|
MailLinks.new(ARGV[0])
|
|
31
31
|
|
data/changes.txt
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
v 1.0
|
|
2
|
+
Browser is opened via Process::spawn().
|
|
3
|
+
|
|
4
|
+
File checks (exist?, readable?, etc.) simplified.
|
|
5
|
+
|
|
6
|
+
YAD added as potential Browser replacement, when none of the other
|
|
7
|
+
can be found. The currently supported programs are thus:
|
|
8
|
+
dillo, w3m, lynx, brave-browser, firefox and YAD.
|
|
9
|
+
|
|
10
|
+
Gemfile updated: License WTFPL and Changelog URL.
|
|
11
|
+
|
data/doc/html/maillinks.html
CHANGED
|
@@ -39,6 +39,8 @@
|
|
|
39
39
|
|
|
40
40
|
<blockquote>
|
|
41
41
|
<p>maillinks [mail-file]</p>
|
|
42
|
+
|
|
43
|
+
<p>maillinks [mail-file] <log level></p>
|
|
42
44
|
</blockquote>
|
|
43
45
|
|
|
44
46
|
<p>or</p>
|
|
@@ -66,6 +68,13 @@
|
|
|
66
68
|
destination, before you engage your web-browser or other tool
|
|
67
69
|
to follow a link.</p>
|
|
68
70
|
|
|
71
|
+
<p><em>MailLinks</em> displays the result, together with the
|
|
72
|
+
original HTML-mail in the first Web-Browser that can be
|
|
73
|
+
executed. At the time of this writing, the possible Browsers
|
|
74
|
+
are: <em>Dillo, W3M, Lynx, Brave-Browser, Firefox</em>. If
|
|
75
|
+
none of these is found, the program aborts with an error
|
|
76
|
+
message.</p>
|
|
77
|
+
|
|
69
78
|
<section id="integration-in-mail-clients">
|
|
70
79
|
<h3>Integration in mail-clients</h3>
|
|
71
80
|
|
|
@@ -93,9 +102,14 @@
|
|
|
93
102
|
<section id="options">
|
|
94
103
|
<h2>Options</h2>
|
|
95
104
|
|
|
96
|
-
<p
|
|
97
|
-
|
|
98
|
-
|
|
105
|
+
<p>When called with a mail file as first argument,
|
|
106
|
+
<em>Maillinks</em> can interpret as second argument a log
|
|
107
|
+
level, to control the verboseness of the program output. The
|
|
108
|
+
default is <em>info</em>, but you can have more detailed
|
|
109
|
+
console output with <em>debug</em>.</p>
|
|
110
|
+
|
|
111
|
+
<p>When used as a filter, reading from <em>STDIN</em>,
|
|
112
|
+
<strong>no additional arguments are accepted</strong>.</p>
|
|
99
113
|
</section>
|
|
100
114
|
|
|
101
115
|
<section id="other-information">
|
|
@@ -119,15 +133,18 @@
|
|
|
119
133
|
<dt>Version</dt>
|
|
120
134
|
|
|
121
135
|
<dd>
|
|
122
|
-
<p>0.1
|
|
136
|
+
<p>0.2.1 (April 2026)</p>
|
|
123
137
|
</dd>
|
|
138
|
+
</dl>
|
|
124
139
|
|
|
140
|
+
<dl class="simple">
|
|
125
141
|
<dt>License</dt>
|
|
126
142
|
|
|
127
143
|
<dd>
|
|
128
144
|
<p><em>Maillinks</em> is published under the conditions
|
|
129
|
-
of the
|
|
130
|
-
|
|
145
|
+
of the <a class="reference external" href=
|
|
146
|
+
"https://www.wtfpl.net/about/">WTFPL</a>, version
|
|
147
|
+
2.0.</p>
|
|
131
148
|
</dd>
|
|
132
149
|
|
|
133
150
|
<dt>Author</dt>
|
data/doc/man/maillinks.1.gz
CHANGED
|
Binary file
|
data/doc/pdf/maillinks.pdf
CHANGED
|
Binary file
|
data/doc/rst/maillinks.rst
CHANGED
|
@@ -7,7 +7,9 @@
|
|
|
7
7
|
|
|
8
8
|
Synopsis
|
|
9
9
|
========
|
|
10
|
-
maillinks [mail-file]
|
|
10
|
+
maillinks [mail-file]
|
|
11
|
+
|
|
12
|
+
maillinks [mail-file] <log level>
|
|
11
13
|
|
|
12
14
|
or
|
|
13
15
|
|
|
@@ -26,6 +28,11 @@ directives which are likely to be addressed to a remotely running application.
|
|
|
26
28
|
below the email-text. You can scrutinize the URL and find information about the
|
|
27
29
|
destination, before you engage your web-browser or other tool to follow a link.
|
|
28
30
|
|
|
31
|
+
*MailLinks* displays the result, together with the original HTML-mail in the
|
|
32
|
+
first Web-Browser that can be executed. At the time of this writing, the
|
|
33
|
+
possible Browsers are: *Dillo, W3M, Lynx, Brave-Browser, Firefox*. If none of
|
|
34
|
+
these is found, the program aborts with an error message.
|
|
35
|
+
|
|
29
36
|
Integration in mail-clients
|
|
30
37
|
----------------------------
|
|
31
38
|
|
|
@@ -46,8 +53,14 @@ macros or similar options can be configured.
|
|
|
46
53
|
|
|
47
54
|
Options
|
|
48
55
|
=========
|
|
49
|
-
|
|
50
|
-
|
|
56
|
+
When called with a mail file as first argument, *Maillinks* can interpret
|
|
57
|
+
as second argument a log level, to control the verboseness of the program
|
|
58
|
+
output. The default is *info*, but you can have more detailed console output
|
|
59
|
+
with *debug*.
|
|
60
|
+
|
|
61
|
+
When used as a filter, reading from *STDIN*, **no additional arguments are
|
|
62
|
+
accepted**.
|
|
63
|
+
|
|
51
64
|
|
|
52
65
|
Other Information
|
|
53
66
|
==================
|
|
@@ -61,11 +74,12 @@ Source-code and Development
|
|
|
61
74
|
the data-archive with *tar -xzf*.
|
|
62
75
|
|
|
63
76
|
Version
|
|
64
|
-
0.1
|
|
77
|
+
0.2.1 (April 2026)
|
|
78
|
+
|
|
79
|
+
.. _WTFPL: https://www.wtfpl.net/about/
|
|
65
80
|
|
|
66
81
|
License
|
|
67
|
-
*Maillinks* is published under the conditions of the
|
|
68
|
-
License, version 3.0 or later.
|
|
82
|
+
*Maillinks* is published under the conditions of the WTFPL_, version 2.0.
|
|
69
83
|
|
|
70
84
|
Author
|
|
71
85
|
Michael Uplawski <michael.uplawski@uplawski.eu>
|
data/lib/basic_logging.rb
CHANGED
|
@@ -57,7 +57,7 @@ module BasicLogging
|
|
|
57
57
|
if(!lv || (lv.respond_to?(:to_int) && lv >= DEBUG && lv <= FATAL) )
|
|
58
58
|
@@log_level = lv
|
|
59
59
|
else
|
|
60
|
-
msg =
|
|
60
|
+
msg = calling_method << ": ERROR : invalid log level \"" << lv.to_s << "\""
|
|
61
61
|
msg << "\n" << "Keepinng old log level " << Levels.keys.detect {| k| Levels[k] == @@log_level}.to_s
|
|
62
62
|
STDERR.puts msg
|
|
63
63
|
puts msg
|
|
@@ -73,14 +73,14 @@ module BasicLogging
|
|
|
73
73
|
elsif !tg || tg.respond_to?(:to_str) && tg.strip.empty?
|
|
74
74
|
@@target = nil
|
|
75
75
|
else
|
|
76
|
-
STDERR.puts
|
|
76
|
+
STDERR.puts calling_method << ': ERROR : target ' << tg.to_str << ' cannot be set'
|
|
77
77
|
STDERR.puts "Keeping old target " << @@target.inspect
|
|
78
78
|
return
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
81
|
|
|
82
|
-
# Output of log messages, depending on the log level
|
|
83
|
-
#
|
|
82
|
+
# Output of log messages, depending on the set log level and the name of the
|
|
83
|
+
# alias method which is actually called.
|
|
84
84
|
def log(message)
|
|
85
85
|
if !BasicLogging.is_muted?(self)
|
|
86
86
|
# how has this method been called?
|
|
@@ -90,7 +90,7 @@ module BasicLogging
|
|
|
90
90
|
# the calling alias.
|
|
91
91
|
format_log( message, mlevel) if @@log_level && Levels[mlevel] >= @@log_level
|
|
92
92
|
else
|
|
93
|
-
STDERR.puts
|
|
93
|
+
STDERR.puts calling_method << ": ERROR : invalid log level \"" << mlevel.to_s << "\""
|
|
94
94
|
end
|
|
95
95
|
end
|
|
96
96
|
end
|
|
@@ -110,6 +110,21 @@ module BasicLogging
|
|
|
110
110
|
end
|
|
111
111
|
end
|
|
112
112
|
|
|
113
|
+
# find the name of the calling object's class or the file name in case of the
|
|
114
|
+
# top level object... or any dumb instance of Object
|
|
115
|
+
def log_name()
|
|
116
|
+
if !@log_name
|
|
117
|
+
clname = self.class.name
|
|
118
|
+
# limit analysis of the call stack to 'Object'.
|
|
119
|
+
if clname == 'Object'
|
|
120
|
+
@log_name = File::basename(caller.last.split(':')[0])
|
|
121
|
+
else
|
|
122
|
+
@log_name = self.class == Class ? self.name.dup << ' [class]' : clname
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
@log_name
|
|
126
|
+
end
|
|
127
|
+
|
|
113
128
|
alias :debug :log
|
|
114
129
|
alias :info :log
|
|
115
130
|
alias :warn :log
|
|
@@ -118,6 +133,31 @@ module BasicLogging
|
|
|
118
133
|
|
|
119
134
|
private
|
|
120
135
|
|
|
136
|
+
# Find the method that called, or 'main' in case of a top level Object.
|
|
137
|
+
# This needs a bunch of memory and slows down the process.
|
|
138
|
+
# Use of this method should be limited.
|
|
139
|
+
def calling_method()
|
|
140
|
+
# find instances other than the current module.
|
|
141
|
+
stack_item = caller.detect do |item|
|
|
142
|
+
item.split(':')[0] != __FILE__
|
|
143
|
+
end
|
|
144
|
+
if stack_item
|
|
145
|
+
if stack_item.include?('#')
|
|
146
|
+
m = stack_item.split(':').last.split("#")[1]
|
|
147
|
+
m.gsub!("'", '') if m && m.include?("'")
|
|
148
|
+
# looks cooler with a class name in front.
|
|
149
|
+
return '#' << m << '()'
|
|
150
|
+
else
|
|
151
|
+
# top level Object
|
|
152
|
+
return stack_item.split(':').last
|
|
153
|
+
end
|
|
154
|
+
else
|
|
155
|
+
# This is dumb but won't hurt a lot.
|
|
156
|
+
return 'from main'
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# could be useful
|
|
121
161
|
def lock_target(&block)
|
|
122
162
|
begin
|
|
123
163
|
if @@target.respond_to?(:flock)
|
|
@@ -128,19 +168,27 @@ module BasicLogging
|
|
|
128
168
|
block.call
|
|
129
169
|
end
|
|
130
170
|
rescue => ex
|
|
131
|
-
STDERR.puts
|
|
171
|
+
STDERR.puts calling_method << ": ERROR : cannot lock target (" << ex.message << ")"
|
|
132
172
|
end
|
|
133
173
|
end
|
|
134
174
|
|
|
135
175
|
# 1 format_log for all loggers.
|
|
136
176
|
def format_log(message, mlevel)
|
|
137
177
|
if @@target
|
|
178
|
+
location = log_name().dup << ' '
|
|
179
|
+
# Limit the memory-hungry analysis of the call stack
|
|
180
|
+
# This also takes about 2.5 times as long.
|
|
181
|
+
if mlevel != :info
|
|
182
|
+
location = log_name().dup << ' ' << calling_method << ' '
|
|
183
|
+
end
|
|
138
184
|
# indicate if a registered class or the registered object of a class is calling.
|
|
139
|
-
|
|
140
|
-
lock_target{@@target.puts '' << name << ' ' << mlevel.to_s << ' ' << Time.now.strftime("%H:%M:%S:%6N") << ': ' << message.gsub("\n", "\n |")}
|
|
185
|
+
lock_target{@@target.puts '' << location << mlevel.to_s << ' ' << Time.now.strftime("%H:%M:%S:%6N") << ': ' << message.gsub("\n", "\n |")}
|
|
141
186
|
end
|
|
142
187
|
end
|
|
143
|
-
end
|
|
188
|
+
end # Module end
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
|
|
144
192
|
#---------test: execute file----------
|
|
145
193
|
if $0 == __FILE__
|
|
146
194
|
Array.extend(BasicLogging)
|
|
@@ -186,14 +234,14 @@ if $0 == __FILE__
|
|
|
186
234
|
obj.warn('warn')
|
|
187
235
|
obj.error('error')
|
|
188
236
|
obj.fatal('fatal')
|
|
189
|
-
|
|
237
|
+
# ---- into file ---
|
|
190
238
|
obj.set_target "/tmp/test_log.log"
|
|
191
|
-
puts "
|
|
239
|
+
puts "------ INFO into #{obj.target}-----------"
|
|
192
240
|
obj.set_level BasicLogging::INFO
|
|
193
241
|
obj.info('info output')
|
|
194
242
|
|
|
195
243
|
obj.info('info output 2')
|
|
196
|
-
puts "---------- invalid -------"
|
|
244
|
+
puts "---------- invalid (fails) -------"
|
|
197
245
|
obj.set_target "/dev/sr0"
|
|
198
246
|
obj.set_level "power"
|
|
199
247
|
end
|
data/lib/color_output.rb
CHANGED
|
@@ -33,22 +33,48 @@ STYLES = {:regular => REGULAR, :bold => BOLD, :underline => UNDERLINE, :blink =>
|
|
|
33
33
|
# Colorizes the given text. Color-code is either an escape-sequence or one of
|
|
34
34
|
# the symbols representing color-names in the COLORS hash.
|
|
35
35
|
def colorize(text, color_code)
|
|
36
|
-
|
|
37
|
-
|
|
36
|
+
# ensure that colors are supported
|
|
37
|
+
if $stdout.tty? && ENV['TERM'] != 'dumb'
|
|
38
|
+
if (COLORS.keys.include?(color_code) )
|
|
39
|
+
"\033[3#{COLORS[color_code]}m#{text}\033[0m"
|
|
40
|
+
else
|
|
41
|
+
"#{color_code}#{text}\033[0m"
|
|
42
|
+
end
|
|
43
|
+
# if Terminal does not support colors
|
|
38
44
|
else
|
|
39
|
-
|
|
45
|
+
text
|
|
40
46
|
end
|
|
41
47
|
end
|
|
42
48
|
|
|
49
|
+
# rgb foreground
|
|
50
|
+
def colorize_RGB(text, r, g, b)
|
|
51
|
+
code = "%s;%s;%s" %[r, g, b]
|
|
52
|
+
"\033[38;2;#{code}m#{text}\033[0m"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# rgb background
|
|
56
|
+
def background_RGB(text, r, g, b)
|
|
57
|
+
code = "%s;%s;%s" %[r, g, b]
|
|
58
|
+
"\033[48;2;#{code}m#{text}\033[0m"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# duplicate code without much intelligence
|
|
43
62
|
def style(text, style_code)
|
|
44
63
|
"#{style_code}#{text}\033[0m"
|
|
45
64
|
end
|
|
65
|
+
|
|
46
66
|
# a function which allows to manipulate every known aspect of the ansi-output.
|
|
47
67
|
def colored_output(output_text, fg_color = :default, bg_color = :default, style = :regular , mode = :neutral )
|
|
48
|
-
|
|
68
|
+
if $stdout.tty? && ENV['TERM'] != 'dumb'
|
|
69
|
+
"\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]
|
|
70
|
+
else
|
|
71
|
+
# fallback for terminals that do not support colors.
|
|
72
|
+
output_text
|
|
73
|
+
end
|
|
49
74
|
end
|
|
50
75
|
|
|
51
76
|
# convenience functions
|
|
77
|
+
def black(text); colorize(text, "\033[30m"); end
|
|
52
78
|
def red(text); colorize(text, "\033[31m"); end
|
|
53
79
|
def green(text); colorize(text, "\033[32m"); end
|
|
54
80
|
def yellow(text); colorize(text, "\033[33m"); end
|
|
@@ -57,9 +83,20 @@ def cyan(text); colorize(text, "\033[36m"); end
|
|
|
57
83
|
def blue(text); colorize(text, "\033[34m"); end
|
|
58
84
|
def white(text); colorize(text, "\033[37m"); end
|
|
59
85
|
|
|
86
|
+
# RGB
|
|
87
|
+
# TODO: Fallbacks from the 256 color palette
|
|
88
|
+
def orange(text); colorize(text, "\033[38;2;255;165;0m"); end
|
|
89
|
+
def pink(text); colorize(text, "\033[38;2;255;0;165m"); end
|
|
90
|
+
def lightred(text); colorize(text, "\033[38;2;255;100;100m"); end
|
|
91
|
+
def lightgreen(text); colorize(text, "\033[38;2;100;255;100m"); end
|
|
92
|
+
def brown(text); colorize(text, "\033[38;2;153;76;0m"); end
|
|
93
|
+
def crimson(text); colorize(text, "\033[38;2;220;20;60m"); end
|
|
94
|
+
|
|
95
|
+
# quick contrast
|
|
60
96
|
def black_on_white(text); colorize(colorize(text, "\033[30m"), "\033[47m");end
|
|
61
97
|
def white_on_black(text); colorize(colorize(text, "\033[37m"), "\033[40m");end
|
|
62
98
|
|
|
99
|
+
# styles
|
|
63
100
|
def bold(text); style(text, "\033[01m");end
|
|
64
101
|
def underline(text); style(text, "\033[04m");end
|
|
65
102
|
|
data/lib/maillinks.rb
CHANGED
|
@@ -13,7 +13,6 @@
|
|
|
13
13
|
***************************************************************************/
|
|
14
14
|
=end
|
|
15
15
|
|
|
16
|
-
require_relative 'file_checking'
|
|
17
16
|
require_relative 'basic_logging'
|
|
18
17
|
require_relative 'constants'
|
|
19
18
|
require_relative 'color_output'
|
|
@@ -28,17 +27,17 @@ class MailLinks
|
|
|
28
27
|
# a file may be piped in from the command-line...
|
|
29
28
|
debug('parameter is ' << (mail ? mail : ' N I L' ))
|
|
30
29
|
if(mail && '-' != mail.strip)
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
debug('will work on mail-file ' << mail)
|
|
38
|
-
@mail = mail
|
|
39
|
-
|
|
40
|
-
File::open(OUT_FILE, 'w+') {|of| of << File::read(@mail) }
|
|
30
|
+
[:exist?, :file?, :readable?].each do |cond|
|
|
31
|
+
if !File.send(cond, mail)
|
|
32
|
+
error(yellow("#{mail}: not #{cond.split('?')[0]}. Aborting!") )
|
|
33
|
+
usage
|
|
34
|
+
exit false
|
|
35
|
+
end
|
|
41
36
|
end
|
|
37
|
+
debug('will work on mail-file ' << mail)
|
|
38
|
+
@mail = mail
|
|
39
|
+
|
|
40
|
+
File::open(OUT_FILE, 'w+') {|of| of << File::read(@mail) }
|
|
42
41
|
elsif(!$<.eof?)
|
|
43
42
|
info('Reading data from STDIN. Hit Ctrl+D to interrupt')
|
|
44
43
|
input = $<.read
|
|
@@ -61,13 +60,23 @@ class MailLinks
|
|
|
61
60
|
private
|
|
62
61
|
|
|
63
62
|
def browser()
|
|
63
|
+
path_dirs = ENV['PATH'].split(':')
|
|
64
64
|
BROWSERS.detect do |b|
|
|
65
65
|
debug 'trying to find browser: ' << b.to_s
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
# array of the directories in $PATH
|
|
67
|
+
|
|
68
|
+
path_dirs.each do |dir_name|
|
|
69
|
+
debug('looking in ' << dir_name)
|
|
70
|
+
return [b] if Dir.entries(dir_name).include?(b)
|
|
68
71
|
end
|
|
69
72
|
end
|
|
70
|
-
|
|
73
|
+
# Look for yad, when everything else has failed.
|
|
74
|
+
path_dirs.each do |dir_name|
|
|
75
|
+
if Dir.entries(dir_name).include?('yad')
|
|
76
|
+
return ['yad', '--browser', '--html', '--width=1000', '--height=800', '--uri=']
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
error 'Cannot find any of the given browsers: ' << BROWSERS.join(', ') << ', yad'
|
|
71
80
|
return nil
|
|
72
81
|
end
|
|
73
82
|
|
|
@@ -85,12 +94,28 @@ class MailLinks
|
|
|
85
94
|
end
|
|
86
95
|
|
|
87
96
|
def show_mail
|
|
97
|
+
# prog is an array of 1 or more elements.
|
|
88
98
|
prog = browser()
|
|
99
|
+
debug 'browser is ' << (prog ? prog.to_s : ' N I L ')
|
|
89
100
|
if prog
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
101
|
+
uri_arg = OUT_FILE
|
|
102
|
+
if prog.length > 1
|
|
103
|
+
# concatenate out_file to the uri-parameter
|
|
104
|
+
uri_arg = prog.pop + OUT_FILE
|
|
105
|
+
end
|
|
106
|
+
# attach the uri_parameter, escape.
|
|
107
|
+
cmd = Escape.shell_command(prog.dup.push uri_arg)
|
|
108
|
+
debug 'command is ' << cmd
|
|
109
|
+
info cyan('<----------- Output from ' << prog[0] << '---------->')
|
|
110
|
+
begin
|
|
111
|
+
pid = Process.spawn(cmd)
|
|
112
|
+
Process.wait
|
|
113
|
+
info cyan('-----------> ' << prog[0] << ' END <----------')
|
|
114
|
+
debug 'removing temporary file ' << OUT_FILE
|
|
115
|
+
File.unlink(OUT_FILE)
|
|
116
|
+
rescue Exception => ex
|
|
117
|
+
error __LINE__.dup << ' ' << ex.message
|
|
118
|
+
end
|
|
94
119
|
else
|
|
95
120
|
fatal yellow('Cannot open browser!' + bold(' ABORTING.') )
|
|
96
121
|
exit false
|
data/maillinks.gemspec
CHANGED
|
@@ -9,17 +9,18 @@ Gem::Specification.new do |s|
|
|
|
9
9
|
s.description = "Marks in an email HTMl-links and creates a list of all links at the bottom of the mail-text. Best used with the Mutt MUA"
|
|
10
10
|
s.authors = AUTHORS
|
|
11
11
|
s.email = MAIL_ADDRESS
|
|
12
|
-
s.files = %w~maillinks~.collect{|f| 'bin/' << f} + %w~constants.rb color_output.rb
|
|
12
|
+
s.files = %w~maillinks~.collect{|f| 'bin/' << f} + %w~constants.rb color_output.rb basic_logging.rb maillinks.rb ~.collect{|f| 'lib/' << f} + %w~html/maillinks.html man/maillinks.1.gz pdf/maillinks.pdf rst/maillinks.rst~.collect{|f| 'doc/' << f} + %w~maillinks.gemspec changes.txt~.collect{|f|f}
|
|
13
13
|
s.homepage = 'https://www.uplawski.eu/software'
|
|
14
14
|
s.requirements = 'Linux, one of the browsers Dillo, W3M, Lynx, Brave-browser or Firefox'
|
|
15
15
|
s.add_runtime_dependency 'nokogiri', '~> 1.19', '>= 1.19.0'
|
|
16
16
|
s.add_runtime_dependency 'escape', '~> 0.0', '>= 0.0.4'
|
|
17
17
|
s.add_runtime_dependency 'mail', '~> 2.9', '>= 2.9.0'
|
|
18
18
|
s.executables = 'maillinks'
|
|
19
|
-
s.license = '
|
|
19
|
+
s.license = 'WTFPL'
|
|
20
20
|
s.required_ruby_version = '>= 4.0'
|
|
21
21
|
s.metadata = {
|
|
22
22
|
"homepage_uri" => 'https://www.uplawski.eu/software/',
|
|
23
|
-
"documentation_uri" => 'https://www.uplawski.eu/software/maillinks/maillinks.html'
|
|
23
|
+
"documentation_uri" => 'https://www.uplawski.eu/software/maillinks/maillinks.html',
|
|
24
|
+
"changelog_uri" => 'https://www.uplawski.eu/software/changelogs/changes_maillinks.txt'
|
|
24
25
|
}
|
|
25
26
|
end
|
metadata
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: maillinks
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0
|
|
4
|
+
version: '1.0'
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michael Uplawski
|
|
8
8
|
bindir: bin
|
|
9
9
|
cert_chain: []
|
|
10
|
-
date: 2026-
|
|
10
|
+
date: 2026-08-23 00:00:00.000000000 Z
|
|
11
11
|
dependencies:
|
|
12
12
|
- !ruby/object:Gem::Dependency
|
|
13
13
|
name: nokogiri
|
|
@@ -78,6 +78,7 @@ extensions: []
|
|
|
78
78
|
extra_rdoc_files: []
|
|
79
79
|
files:
|
|
80
80
|
- bin/maillinks
|
|
81
|
+
- changes.txt
|
|
81
82
|
- doc/html/maillinks.html
|
|
82
83
|
- doc/man/maillinks.1.gz
|
|
83
84
|
- doc/pdf/maillinks.pdf
|
|
@@ -85,15 +86,15 @@ files:
|
|
|
85
86
|
- lib/basic_logging.rb
|
|
86
87
|
- lib/color_output.rb
|
|
87
88
|
- lib/constants.rb
|
|
88
|
-
- lib/file_checking.rb
|
|
89
89
|
- lib/maillinks.rb
|
|
90
90
|
- maillinks.gemspec
|
|
91
91
|
homepage: https://www.uplawski.eu/software
|
|
92
92
|
licenses:
|
|
93
|
-
-
|
|
93
|
+
- WTFPL
|
|
94
94
|
metadata:
|
|
95
95
|
homepage_uri: https://www.uplawski.eu/software/
|
|
96
96
|
documentation_uri: https://www.uplawski.eu/software/maillinks/maillinks.html
|
|
97
|
+
changelog_uri: https://www.uplawski.eu/software/changelogs/changes_maillinks.txt
|
|
97
98
|
rdoc_options: []
|
|
98
99
|
require_paths:
|
|
99
100
|
- lib
|
|
@@ -109,7 +110,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
109
110
|
version: '0'
|
|
110
111
|
requirements:
|
|
111
112
|
- Linux, one of the browsers Dillo, W3M, Lynx, Brave-browser or Firefox
|
|
112
|
-
rubygems_version: 4.0.
|
|
113
|
+
rubygems_version: 4.0.18
|
|
113
114
|
specification_version: 4
|
|
114
115
|
summary: Documentation in HTML formatted. Alternative Browsers allowed.
|
|
115
116
|
test_files: []
|
data/lib/file_checking.rb
DELETED
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
#encoding: UTF-8
|
|
2
|
-
=begin
|
|
3
|
-
/***************************************************************************
|
|
4
|
-
* 2011-2026, Michael Uplawski <michael.uplawski@uplawski.eu> *
|
|
5
|
-
* This program is free software; you can redistribute it and/or modify *
|
|
6
|
-
* it under the terms of the WTFPL 2.0 or later, see *
|
|
7
|
-
* http://www.wtfpl.net/about/ *
|
|
8
|
-
* *
|
|
9
|
-
* This program is distributed in the hope that it will be useful, *
|
|
10
|
-
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
11
|
-
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
|
12
|
-
* *
|
|
13
|
-
***************************************************************************/
|
|
14
|
-
=end
|
|
15
|
-
|
|
16
|
-
=begin
|
|
17
|
-
A module to facilitate frequently occuring checks on
|
|
18
|
-
file-system objects
|
|
19
|
-
=end
|
|
20
|
-
module File_Checking
|
|
21
|
-
|
|
22
|
-
@@text_messages = {
|
|
23
|
-
:exist? => "does not exist!",
|
|
24
|
-
:exist => "does not exist!",
|
|
25
|
-
:readable? => "is not readable!",
|
|
26
|
-
:readable => "is not readable!",
|
|
27
|
-
:executable? => "is not executable!",
|
|
28
|
-
:executable => "is not executable!",
|
|
29
|
-
:writable? => "is not writable!",
|
|
30
|
-
:writable => "is not writable!",
|
|
31
|
-
:directory? => "is not a directory!",
|
|
32
|
-
:directory => "is not a directory!",
|
|
33
|
-
:file? => "is not a file!",
|
|
34
|
-
:file => "is not a file!",
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
# Checks if the file with the name from the first
|
|
38
|
-
# parameter has the properties, listed in the second.
|
|
39
|
-
# The messages parameter is an array of one or several
|
|
40
|
-
# of :exist?, :readable?, :writable?, :directory? or
|
|
41
|
-
# their string-representations, respectively.
|
|
42
|
-
# Returns nil in case of success, otherwise an
|
|
43
|
-
# informative message, describing the first negative
|
|
44
|
-
# test-result.
|
|
45
|
-
def file_check(file, *messages)
|
|
46
|
-
File_Checking.file_check(file, *messages)
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
# Checks if the file with the name from the first
|
|
50
|
-
# parameter has the properties, listed in the second.
|
|
51
|
-
# The messages parameter is an array of one or all
|
|
52
|
-
# of :exist?, :readable?, :writable?, :directory? or
|
|
53
|
-
# their string-representations, respectively.
|
|
54
|
-
# Returns nil in case of success, otherwise an
|
|
55
|
-
# informative message, describing the first negative
|
|
56
|
-
# test-result.
|
|
57
|
-
def self.file_check(file, *messages)
|
|
58
|
-
msg = nil
|
|
59
|
-
if(file && messages.respond_to?(:to_ary) && !messages.empty?)
|
|
60
|
-
messages.each do |k|
|
|
61
|
-
if(! k.to_s.end_with?('?'))
|
|
62
|
-
k = (k.to_s << '?').to_sym
|
|
63
|
-
end
|
|
64
|
-
@log.debug ('checking ' << k.to_s) if @log
|
|
65
|
-
if(msg == nil && File.respond_to?(k) && ! File.send(k, file.to_s))
|
|
66
|
-
msg = "#{file} #{@@text_messages[k.to_sym]}"
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
70
|
-
msg
|
|
71
|
-
end
|
|
72
|
-
alias :check_file :file_check
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
=begin
|
|
76
|
-
# example
|
|
77
|
-
|
|
78
|
-
include File_Checking
|
|
79
|
-
msg = file_check('some_file.txt', [:exist?, :readable?, 'writable'])
|
|
80
|
-
puts msg if msg
|
|
81
|
-
=end
|