maillinks 0.2.1 → 1.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 528a601eb7ae4a84df0fad6c48c6bce9f405f591f7ba841406c5702385c3f0e3
4
- data.tar.gz: 7a4cf22b76902654c65d52cc9a54d9fe385ac6fe5d37b066f53e48a9d718ee21
3
+ metadata.gz: d083333310f5787e778bb24a2532f2c9f284b2a1576c1c2db1942f3224bb738f
4
+ data.tar.gz: 27619b93b517807ad3b23eecc737bd830db63f0e98f721a9796a0f3c159403d7
5
5
  SHA512:
6
- metadata.gz: d823941066f9e031e8f7be9f310cebfd0a819194bc5920e218e4ddca712f1b4779e44297fd2948748a81fcac31f8a67677497bb8bb69dd6e38d3234504862d8f
7
- data.tar.gz: 2b54a0831294dad1079ae87cc2ee385fa51c0058453f46d9142ece56f175a083eff586221558066785c730d3af6afb4dcf5bffc0fa4117056715751e02265b45
6
+ metadata.gz: 240b806c7dd973e3fd7babe3caab44e132848a51f08a98ff1a821267f8de0654424ccc179cc762fb87f7d6afebd21cdf4a8faa0cc3a93811e273d5b91392963d
7
+ data.tar.gz: c8a5c84f1344f47cfd184e1712c32af6a1d21dfeca128846a58ef6b8ed441e8a5c56183e09ead59d06f6c3fff8a4b23d6c9189821dfddc3295cbcafed3817284
data/bin/maillinks CHANGED
@@ -20,12 +20,11 @@ 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
-
28
26
  set_level($LOG_LEVEL)
27
+ debug 'log level will be ' << $LOG_LEVEL.to_s
29
28
 
30
29
  MailLinks.new(ARGV[0])
31
30
 
data/changes.txt ADDED
@@ -0,0 +1,16 @@
1
+ v 1.1
2
+ -) Bugfix: programming error corrected: :symbol.splt to :symbol.to_s.split
3
+ The error only happens with invalid input files, the program will
4
+ abort anyway.
5
+
6
+ v 1.0
7
+ Browser is opened via Process::spawn().
8
+
9
+ File checks (exist?, readable?, etc.) simplified.
10
+
11
+ YAD added as potential Browser replacement, when none of the other
12
+ can be found. The currently supported programs are thus:
13
+ dillo, w3m, lynx, brave-browser, firefox and YAD.
14
+
15
+ Gemfile updated: License WTFPL and Changelog URL.
16
+
@@ -39,6 +39,8 @@
39
39
 
40
40
  <blockquote>
41
41
  <p>maillinks [mail-file]</p>
42
+
43
+ <p>maillinks [mail-file] &lt;log level&gt;</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><em>Maillinks</em> does currently not interpret any
97
- command line arguments other than the name of a mail-file to
98
- analyze.</p>
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.2 (May 2017)</p>
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 GNU General Public License, version 3.0 or
130
- later.</p>
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>
Binary file
Binary file
@@ -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
- *Maillinks* does currently not interpret any command line arguments other than
50
- the name of a mail-file to analyze.
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.2 (May 2017)
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 GNU General Public
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 = __FILE__.dup << ": ERROR : invalid log level \"" << lv.to_s << "\""
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 __FILE__.dup << ': ERROR : target ' << tg << ' cannot be set'
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 set for the calling class
83
- # and the name of the alias method which is actually called.
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 __FILE__.dup << ": ERROR : invalid log level \"" << mlevel.to_s << "\""
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 __FILE__.dup << ": ERROR : cannot lock target (" << ex.message << ")"
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
- name = self.class == Class ? self.name.dup << ' [class]' : self.class.name
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
- puts " ------ Output into file ----"
237
+ # ---- into file ---
190
238
  obj.set_target "/tmp/test_log.log"
191
- puts " ------ INFO -----------"
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
- if (COLORS.keys.include?(color_code) )
37
- "\033[3#{COLORS[color_code]}m#{text}\033[0m"
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
- "#{color_code}#{text}\033[0m"
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
- "\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]
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
- msg = File_Checking.file_check(mail, :exist, :file, :readable)
32
- if(msg)
33
- error(yellow(msg) )
34
- usage
35
- exit false
36
- else
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
+ fatal(lightred("Awkward file: #{mail} – \"not #{cond.to_s.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
- ENV['PATH'].split(':').each do |dir_name|
67
- return b if Dir.entries(dir_name).include?(b)
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
- error 'Cannot find any of the given browsers: ' << BROWSERS.join(', ')
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
- cmd = Escape.shell_command([prog, OUT_FILE])
91
- info cyan('<----------- Output from ' << prog << '---------->')
92
- system(cmd)
93
- info cyan('-----------> ' << prog << ' END <----------')
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
@@ -138,8 +163,16 @@ class MailLinks
138
163
  end
139
164
  links_hash = Hash.new
140
165
  a_nodes.each_with_index do |a, i|
166
+
141
167
  debug('a is ' << a.to_s.gsub("=\" ", ''))
142
168
  caption = a.inner_text.to_s.strip
169
+ has_image = a.at_css('img')
170
+ # If there's an image, include its source in the debug or caption
171
+ if has_image
172
+ src = has_image['src']
173
+ # Optional: modify caption to indicate it has an image
174
+ caption = "#{caption} (Image: #{src})"
175
+ end
143
176
  href = a.attribute('href')
144
177
  if(href)
145
178
  debug('href is: ' << href.to_s)
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 file_checking.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~.collect{|f|f}
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 = 'Nonstandard'
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,115 +1,129 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maillinks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: "1.1"
5
5
  platform: ruby
6
6
  authors:
7
- - Michael Uplawski
7
+ - Michael Uplawski
8
8
  bindir: bin
9
9
  cert_chain: []
10
- date: 2026-04-28 00:00:00.000000000 Z
10
+ date: 2026-09-11 00:00:00.000000000 Z
11
11
  dependencies:
12
- - !ruby/object:Gem::Dependency
13
- name: nokogiri
14
- requirement: !ruby/object:Gem::Requirement
15
- requirements:
16
- - - "~>"
17
- - !ruby/object:Gem::Version
18
- version: '1.19'
19
- - - ">="
20
- - !ruby/object:Gem::Version
21
- version: 1.19.0
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- requirements:
26
- - - "~>"
27
- - !ruby/object:Gem::Version
28
- version: '1.19'
29
- - - ">="
30
- - !ruby/object:Gem::Version
31
- version: 1.19.0
32
- - !ruby/object:Gem::Dependency
33
- name: escape
34
- requirement: !ruby/object:Gem::Requirement
35
- requirements:
36
- - - "~>"
37
- - !ruby/object:Gem::Version
38
- version: '0.0'
39
- - - ">="
40
- - !ruby/object:Gem::Version
41
- version: 0.0.4
42
- type: :runtime
43
- prerelease: false
44
- version_requirements: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - "~>"
47
- - !ruby/object:Gem::Version
48
- version: '0.0'
49
- - - ">="
50
- - !ruby/object:Gem::Version
51
- version: 0.0.4
52
- - !ruby/object:Gem::Dependency
53
- name: mail
54
- requirement: !ruby/object:Gem::Requirement
55
- requirements:
56
- - - "~>"
57
- - !ruby/object:Gem::Version
58
- version: '2.9'
59
- - - ">="
60
- - !ruby/object:Gem::Version
61
- version: 2.9.0
62
- type: :runtime
63
- prerelease: false
64
- version_requirements: !ruby/object:Gem::Requirement
65
- requirements:
66
- - - "~>"
67
- - !ruby/object:Gem::Version
68
- version: '2.9'
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- version: 2.9.0
72
- description: Marks in an email HTMl-links and creates a list of all links at the bottom
73
- of the mail-text. Best used with the Mutt MUA
12
+ - !ruby/object:Gem::Dependency
13
+ name: nokogiri
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ -
17
+ - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: "1.19"
20
+ -
21
+ - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 1.19.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: !ruby/object:Gem::Requirement
27
+ requirements:
28
+ -
29
+ - ~>
30
+ - !ruby/object:Gem::Version
31
+ version: "1.19"
32
+ -
33
+ - ">="
34
+ - !ruby/object:Gem::Version
35
+ version: 1.19.0
36
+ - !ruby/object:Gem::Dependency
37
+ name: escape
38
+ requirement: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ -
41
+ - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: "0.0"
44
+ -
45
+ - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.0.4
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ -
53
+ - ~>
54
+ - !ruby/object:Gem::Version
55
+ version: "0.0"
56
+ -
57
+ - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 0.0.4
60
+ - !ruby/object:Gem::Dependency
61
+ name: mail
62
+ requirement: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ -
65
+ - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: "2.9"
68
+ -
69
+ - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 2.9.0
72
+ type: :runtime
73
+ prerelease: false
74
+ version_requirements: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ -
77
+ - ~>
78
+ - !ruby/object:Gem::Version
79
+ version: "2.9"
80
+ -
81
+ - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: 2.9.0
84
+ 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
74
85
  email: michael.uplawski@uplawski.eu
75
86
  executables:
76
- - maillinks
87
+ - maillinks
77
88
  extensions: []
78
89
  extra_rdoc_files: []
79
90
  files:
80
- - bin/maillinks
81
- - doc/html/maillinks.html
82
- - doc/man/maillinks.1.gz
83
- - doc/pdf/maillinks.pdf
84
- - doc/rst/maillinks.rst
85
- - lib/basic_logging.rb
86
- - lib/color_output.rb
87
- - lib/constants.rb
88
- - lib/file_checking.rb
89
- - lib/maillinks.rb
90
- - maillinks.gemspec
91
- homepage: https://www.uplawski.eu/software
91
+ - bin/maillinks
92
+ - changes.txt
93
+ - doc/html/maillinks.html
94
+ - doc/man/maillinks.1.gz
95
+ - doc/pdf/maillinks.pdf
96
+ - doc/rst/maillinks.rst
97
+ - lib/basic_logging.rb
98
+ - lib/color_output.rb
99
+ - lib/constants.rb
100
+ - lib/maillinks.rb
101
+ - maillinks.gemspec
102
+ homepage: "https://www.uplawski.eu/software"
92
103
  licenses:
93
- - Nonstandard
104
+ - WTFPL
94
105
  metadata:
95
- homepage_uri: https://www.uplawski.eu/software/
96
- documentation_uri: https://www.uplawski.eu/software/maillinks/maillinks.html
106
+ homepage_uri: "https://www.uplawski.eu/software/"
107
+ documentation_uri: "https://www.uplawski.eu/software/maillinks/maillinks.html"
108
+ changelog_uri: "https://www.uplawski.eu/software/changelogs/changes_maillinks.txt"
97
109
  rdoc_options: []
98
110
  require_paths:
99
- - lib
111
+ - lib
100
112
  required_ruby_version: !ruby/object:Gem::Requirement
101
113
  requirements:
102
- - - ">="
103
- - !ruby/object:Gem::Version
104
- version: '4.0'
114
+ -
115
+ - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: "4.0"
105
118
  required_rubygems_version: !ruby/object:Gem::Requirement
106
119
  requirements:
107
- - - ">="
108
- - !ruby/object:Gem::Version
109
- version: '0'
120
+ -
121
+ - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: "0"
110
124
  requirements:
111
- - Linux, one of the browsers Dillo, W3M, Lynx, Brave-browser or Firefox
112
- rubygems_version: 4.0.10
125
+ - "Linux, one of the browsers Dillo, W3M, Lynx, Brave-browser or Firefox"
126
+ rubygems_version: 4.1.0.beta1
113
127
  specification_version: 4
114
128
  summary: Documentation in HTML formatted. Alternative Browsers allowed.
115
129
  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