maillinks 0.1.5 → 0.2.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.
@@ -0,0 +1,201 @@
1
+ #!/bin/env ruby
2
+ #encoding: UTF-8
3
+ =begin
4
+ /***************************************************************************
5
+ * 2023-2026, Michael Uplawski <michael.uplawski@uplawski.eu> *
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, see *
8
+ * http://www.wtfpl.net/about/ *
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
+ #
18
+ # Simplified logging.
19
+ # See example code at the bottom of this file.
20
+ # Execute this file to see the output.
21
+ module BasicLogging
22
+
23
+ DEBUG = 0
24
+ INFO = 1
25
+ WARN = 2
26
+ ERROR = 3
27
+ FATAL = 4
28
+ UNKNOWN = nil
29
+
30
+ # this is mainly for the translation of method calls into log levels
31
+ Levels = {:debug => DEBUG, :info => INFO, :warn => WARN, :error => ERROR,
32
+ :fatal => FATAL, :unknown => UNKNOWN}
33
+
34
+ @@log_level = UNKNOWN
35
+ @@target = STDOUT
36
+ @@muted = []
37
+
38
+ # do not log, if caller is obj (class or instance)
39
+ def self.mute(obj)
40
+ name = obj.class == Class ? obj.name.dup : obj.class.name
41
+ @@muted << name
42
+ end
43
+
44
+ def self.is_muted?(obj)
45
+ name = obj.class == Class ? obj.name.dup : obj.class.name
46
+ @@muted.include?(name)
47
+ end
48
+
49
+ # set the log level
50
+ def set_level(lv)
51
+ if lv.respond_to?(:to_str) && Levels.keys.include?(lv.strip.to_sym)
52
+ lv = Levels[lv.to_sym]
53
+ elsif lv.respond_to?(:to_sym) && Levels.keys.include?(lv)
54
+ lv = Levels[lv]
55
+ end
56
+
57
+ if(!lv || (lv.respond_to?(:to_int) && lv >= DEBUG && lv <= FATAL) )
58
+ @@log_level = lv
59
+ else
60
+ msg = __FILE__.dup << ": ERROR : invalid log level \"" << lv.to_s << "\""
61
+ msg << "\n" << "Keepinng old log level " << Levels.keys.detect {| k| Levels[k] == @@log_level}.to_s
62
+ STDERR.puts msg
63
+ puts msg
64
+ end
65
+ end
66
+
67
+ # set the log target
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
+ elsif !tg || tg.respond_to?(:to_str) && tg.strip.empty?
74
+ @@target = nil
75
+ else
76
+ STDERR.puts __FILE__.dup << ': ERROR : target ' << tg << ' cannot be set'
77
+ STDERR.puts "Keeping old target " << @@target.inspect
78
+ return
79
+ end
80
+ end
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.
84
+ def log(message)
85
+ if !BasicLogging.is_muted?(self)
86
+ # how has this method been called?
87
+ mlevel = __callee__
88
+ if Levels.has_key?(mlevel) && Levels[mlevel] <= FATAL
89
+ # output only for levels equal or above the value that corresponds to
90
+ # the calling alias.
91
+ format_log( message, mlevel) if @@log_level && Levels[mlevel] >= @@log_level
92
+ else
93
+ STDERR.puts __FILE__.dup << ": ERROR : invalid log level \"" << mlevel.to_s << "\""
94
+ end
95
+ end
96
+ end
97
+
98
+ def target
99
+ @@target.path if @@target
100
+ end
101
+
102
+ def level
103
+ @@level.to_s if @@level
104
+ end
105
+
106
+ # Clear the log (-file)
107
+ def clear_log
108
+ if @@target && @@target.respond_to?(:truncate)
109
+ lock_target{ @@target.truncate(0) }
110
+ end
111
+ end
112
+
113
+ alias :debug :log
114
+ alias :info :log
115
+ alias :warn :log
116
+ alias :error :log
117
+ alias :fatal :log
118
+
119
+ private
120
+
121
+ def lock_target(&block)
122
+ begin
123
+ if @@target.respond_to?(:flock)
124
+ @@target.flock(File::LOCK_EX)
125
+ block.call
126
+ @@target.flock(File::LOCK_UN)
127
+ elsif @@target.respond_to?(:to_io)
128
+ block.call
129
+ end
130
+ rescue => ex
131
+ STDERR.puts __FILE__.dup << ": ERROR : cannot lock target (" << ex.message << ")"
132
+ end
133
+ end
134
+
135
+ # 1 format_log for all loggers.
136
+ def format_log(message, mlevel)
137
+ if @@target
138
+ # 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 |")}
141
+ end
142
+ end
143
+ end
144
+ #---------test: execute file----------
145
+ if $0 == __FILE__
146
+ Array.extend(BasicLogging)
147
+ Array.set_level(BasicLogging::INFO)
148
+ Array.info('TEST')
149
+ ar = Array.new
150
+ ar.extend(BasicLogging)
151
+ # --- no output :
152
+ l = __LINE__
153
+ ar.debug(l.next.to_s << ': debug-test 0')
154
+ # output
155
+ ar.set_level(BasicLogging::DEBUG)
156
+ l = __LINE__
157
+ ar.debug(l.next.to_s << ': debug-test 1')
158
+
159
+ obj = Object.new
160
+ obj.extend(BasicLogging)
161
+ obj.set_level(BasicLogging::DEBUG)
162
+ puts "--------debug-----------"
163
+ obj.debug('debug')
164
+ obj.info('info')
165
+ obj.warn('warn')
166
+ obj.error('error')
167
+ obj.fatal('fatal')
168
+ puts "--------info-----------"
169
+ obj.set_level("info")
170
+ obj.debug('debug')
171
+ obj.info('info')
172
+ obj.warn('warn')
173
+ obj.error('error')
174
+ obj.fatal('fatal')
175
+ puts "--------fatal-----------"
176
+ obj.set_level("fatal")
177
+ obj.debug('debug')
178
+ obj.info('info')
179
+ obj.warn('warn')
180
+ obj.error('error')
181
+ obj.fatal('fatal')
182
+ puts "--------UNKNOWN-----------"
183
+ obj.set_level(nil)
184
+ obj.debug('debug')
185
+ obj.info('info')
186
+ obj.warn('warn')
187
+ obj.error('error')
188
+ obj.fatal('fatal')
189
+ puts " ------ Output into file ----"
190
+ obj.set_target "/tmp/test_log.log"
191
+ puts " ------ INFO -----------"
192
+ obj.set_level BasicLogging::INFO
193
+ obj.info('info output')
194
+
195
+ obj.info('info output 2')
196
+ puts "---------- invalid -------"
197
+ obj.set_target "/dev/sr0"
198
+ obj.set_level "power"
199
+ end
200
+
201
+ # EOF
@@ -0,0 +1,65 @@
1
+ #encoding: UTF-8
2
+ =begin
3
+ /***************************************************************************
4
+ * 2023-2024, 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
+ # Functions to apply colors to terminal output.
17
+ # This is stolen from the Internet and I have lost track of my own additions
18
+ # and modifications.
19
+
20
+ COLORS = {:default => 9, :black => 0, :red => 1, :green => 2, :yellow => 3, :blue => 4, :purple => 5, :cyan => 6, :white => 7 }
21
+
22
+ BG = 4
23
+ FG = 3
24
+ REGULAR = 0
25
+ BOLD = 1
26
+ UNDERLINE = 4
27
+ BLINK = 5
28
+ SWAP = 7
29
+ NEUTRAL = 0
30
+
31
+ STYLES = {:regular => REGULAR, :bold => BOLD, :underline => UNDERLINE, :blink => BLINK, :swap => SWAP, :neutral => NEUTRAL}
32
+
33
+ # Colorizes the given text. Color-code is either an escape-sequence or one of
34
+ # the symbols representing color-names in the COLORS hash.
35
+ def colorize(text, color_code)
36
+ if (COLORS.keys.include?(color_code) )
37
+ "\033[3#{COLORS[color_code]}m#{text}\033[0m"
38
+ else
39
+ "#{color_code}#{text}\033[0m"
40
+ end
41
+ end
42
+
43
+ def style(text, style_code)
44
+ "#{style_code}#{text}\033[0m"
45
+ end
46
+ # a function which allows to manipulate every known aspect of the ansi-output.
47
+ 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]
49
+ end
50
+
51
+ # convenience functions
52
+ def red(text); colorize(text, "\033[31m"); end
53
+ def green(text); colorize(text, "\033[32m"); end
54
+ def yellow(text); colorize(text, "\033[33m"); end
55
+ def purple(text); colorize(text, "\033[35m"); end
56
+ def cyan(text); colorize(text, "\033[36m"); end
57
+ def blue(text); colorize(text, "\033[34m"); end
58
+ def white(text); colorize(text, "\033[37m"); end
59
+
60
+ def black_on_white(text); colorize(colorize(text, "\033[30m"), "\033[47m");end
61
+ def white_on_black(text); colorize(colorize(text, "\033[37m"), "\033[40m");end
62
+
63
+ def bold(text); style(text, "\033[01m");end
64
+ def underline(text); style(text, "\033[04m");end
65
+
data/lib/constants.rb CHANGED
@@ -1,22 +1,15 @@
1
1
  #encoding: UTF-8
2
2
  =begin
3
3
  /***************************************************************************
4
- * ©2015-2015 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
- * *
4
+ * 2023-2026, Michael Uplawski <michael.uplawski@uplawski.eu> *
6
5
  * 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. *
6
+ * it under the terms of the WTFPL 2.0 or later, see *
7
+ * http://www.wtfpl.net/about/ *
10
8
  * *
11
9
  * This program is distributed in the hope that it will be useful, *
12
10
  * 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. *
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
15
12
  * *
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
13
  ***************************************************************************/
21
14
  =end
22
15
 
@@ -26,5 +19,7 @@ require 'tmpdir'
26
19
  # ignore the rules for HTML. Now they write HTML-mail.
27
20
  Block_Tags = %w~body div p hr table img~
28
21
 
29
- BROWSER = "/usr/bin/w3m"
22
+ # use the first one available
23
+ BROWSERS = ['dillo', 'w3m', 'lynx', 'brave-browser', 'firefox']
24
+
30
25
  OUT_FILE = "%s/mail_message.html" %Dir.tmpdir
data/lib/file_checking.rb CHANGED
@@ -1,22 +1,15 @@
1
1
  #encoding: UTF-8
2
2
  =begin
3
3
  /***************************************************************************
4
- * ©2011-2013 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
- * *
4
+ * 2011-2026, Michael Uplawski <michael.uplawski@uplawski.eu> *
6
5
  * 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. *
6
+ * it under the terms of the WTFPL 2.0 or later, see *
7
+ * http://www.wtfpl.net/about/ *
10
8
  * *
11
9
  * This program is distributed in the hope that it will be useful, *
12
10
  * 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. *
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
15
12
  * *
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
13
  ***************************************************************************/
21
14
  =end
22
15
 
data/lib/maillinks.rb CHANGED
@@ -1,86 +1,100 @@
1
1
  #encoding: UTF-8
2
2
  =begin
3
3
  /***************************************************************************
4
- * ©2015-2015 Michael Uplawski <michael.uplawski@uplawski.eu> *
5
- * *
4
+ * 2023-2026, Michael Uplawski <michael.uplawski@uplawski.eu> *
6
5
  * 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. *
6
+ * it under the terms of the WTFPL 2.0 or later, see *
7
+ * http://www.wtfpl.net/about/ *
10
8
  * *
11
9
  * This program is distributed in the hope that it will be useful, *
12
10
  * 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. *
11
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
15
12
  * *
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
13
  ***************************************************************************/
21
14
  =end
22
15
 
23
16
  require_relative 'file_checking'
24
- require_relative 'logging'
17
+ require_relative 'basic_logging'
25
18
  require_relative 'constants'
19
+ require_relative 'color_output'
26
20
  require 'mail'
27
21
  require 'nokogiri'
28
22
  require 'escape'
29
23
 
30
24
  # show me the urls.
31
25
  class MailLinks
32
- include Logging
26
+ include BasicLogging
33
27
  def initialize(mail = nil)
34
-
35
- init_logger(STDOUT)
36
- # a file may be piped in from the command-line...
37
- @log.debug('parameter is ' << (mail ? mail : ' N I L' ))
28
+ # a file may be piped in from the command-line...
29
+ debug('parameter is ' << (mail ? mail : ' N I L' ))
38
30
  if(mail && '-' != mail.strip)
39
31
  msg = File_Checking.file_check(mail, :exist, :file, :readable)
40
32
  if(msg)
41
- @log.error(msg)
33
+ error(yellow(msg) )
42
34
  usage
43
35
  exit false
44
36
  else
45
- @log.debug('will work on mail-file ' << mail)
37
+ debug('will work on mail-file ' << mail)
46
38
  @mail = mail
47
39
 
48
40
  File::open(OUT_FILE, 'w+') {|of| of << File::read(@mail) }
49
41
  end
50
42
  elsif(!$<.eof?)
51
- @log.debug('Reading data from STDIN. Hit Ctrl+D to interrupt')
43
+ info('Reading data from STDIN. Hit Ctrl+D to interrupt')
52
44
  input = $<.read
53
- @log.debug('input length is ' << input.length.to_s)
45
+ debug('input length is ' << input.length.to_s)
54
46
  if(input.length < 10)
55
- @log.error('insufficient input data')
56
- @log.error('No mail text provided')
47
+ error(yellow('insufficient input data'))
48
+ error(yellow('No mail text provided'))
57
49
  usage()
58
50
  exit false
59
51
  end
60
52
  # ... provide a temporary file in that case,
61
- # @mail = OUT_FILE
62
53
  File.open(OUT_FILE, 'w+') {|of| of << input}
63
54
  @mail = OUT_FILE.dup
64
- @log.debug('Temporary eml-file is written.')
55
+ debug('Temporary eml-file is written.')
65
56
  end
66
57
 
67
58
  procede
68
59
  end
69
60
 
70
61
  private
62
+
63
+ def browser()
64
+ BROWSERS.detect do |b|
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)
68
+ end
69
+ end
70
+ error 'Cannot find any of the given browsers: ' << BROWSERS.join(', ')
71
+ return nil
72
+ end
73
+
71
74
  def procede
72
75
  handle_mail
73
76
  show_mail
74
77
  end
75
78
  def usage
76
- msg = 'Usage: ' << $0 << ' ' << '<mail-file>'
79
+ msg = "\nUsage: " << $0 << ' ' << '<mail-file>'
77
80
  msg << "\n or: " << 'cat <mail-file> |' << $0
81
+ msg << "\nYou can name a log level as second parameter:\n"
82
+ msg << " " << $0 << ' ' << '<mail-file>' << ' ' << 'debug'
83
+ msg << "\nThis will create more verbose program output.\n"
78
84
  puts msg
79
85
  end
80
86
 
81
87
  def show_mail
82
- cmd = Escape.shell_command([BROWSER, OUT_FILE])
83
- system(cmd)
88
+ prog = browser()
89
+ if prog
90
+ cmd = Escape.shell_command([prog, OUT_FILE])
91
+ info cyan('<----------- Output from ' << prog << '---------->')
92
+ system(cmd)
93
+ info cyan('-----------> ' << prog << ' END <----------')
94
+ else
95
+ fatal yellow('Cannot open browser!' + bold(' ABORTING.') )
96
+ exit false
97
+ end
84
98
  end
85
99
 
86
100
  def handle_mail
@@ -89,8 +103,8 @@ class MailLinks
89
103
  mail_body = mail_content.split("</head>")[1].split("</html>")[0]
90
104
  mail_body = Mail::Encodings::QuotedPrintable.decode(mail_body)
91
105
  rescue Exception => ex
92
- @log.error('Cannot find the html-body in this mail. Maybe it is not a HTML-mail?')
93
- @log.debug(ex.message)
106
+ error('Cannot find the html-body in this mail. Maybe it is not a HTML-mail?')
107
+ debug(ex.message)
94
108
  end
95
109
  if !mail_body
96
110
  mail_body = mail_content
@@ -100,7 +114,7 @@ class MailLinks
100
114
 
101
115
  a_nodes = html_mail.xpath(".//a")
102
116
  if(! a_nodes || a_nodes.empty? )
103
- @log.info('no links in this mail')
117
+ info(green('no links in this mail') )
104
118
  exit true
105
119
  end
106
120
  begin
@@ -114,30 +128,30 @@ class MailLinks
114
128
  body.add_child("<hr/>")
115
129
  body.add_child("<h2>HTML-links in this mail</h2>")[0]
116
130
  if(!body)
117
- @log.error('cannot find a body-tag in this mail')
131
+ error('cannot find a body-tag in this mail')
118
132
  exit false
119
133
  end
120
134
  dl = body.add_child("<dl id='links'></dl>")[0]
121
135
  if(!dl)
122
- @log.error('cannot add a list-tag')
136
+ error('cannot add a list-tag')
123
137
  exit false
124
138
  end
125
139
  links_hash = Hash.new
126
140
  a_nodes.each_with_index do |a, i|
127
- @log.debug('a is ' << a.to_s.gsub("=\" ", ''))
141
+ debug('a is ' << a.to_s.gsub("=\" ", ''))
128
142
  caption = a.inner_text.to_s.strip
129
143
  href = a.attribute('href')
130
144
  if(href)
131
- @log.debug('href is: ' << href.to_s)
145
+ debug('href is: ' << href.to_s)
132
146
  link = href.content
133
- @log.debug('link is ex href.content: ' << link.to_s)
147
+ debug('link is ex href.content: ' << link.to_s)
134
148
  a.add_next_sibling("<span>[" << (i.next).to_s << "]</span>")
135
149
  dl.add_child("<dt>%i) %s</dt>"%[i.next, caption])
136
- dl.add_child("<dd style='white-space:nowrap;'><a href='%s'>%s</a></dd>"%[link,link])
150
+ dl.add_child("<dd style='white-space:nowrap;'><a style='white-space:nowrap;' href='%s'>%s</a></dd>"%[link,link])
137
151
  end
138
152
  end
139
153
  rescue Exception => ex
140
- @log.error("cannot handle the HTML in this mail: " << ex.message)
154
+ error(yellow("cannot handle the HTML in this mail: ") << bold(ex.message) )
141
155
  exit false
142
156
  end
143
157
 
data/maillinks.gemspec CHANGED
@@ -1,20 +1,25 @@
1
+ require_relative "lib/version"
1
2
  require 'date'
2
3
 
3
4
  Gem::Specification.new do |s|
4
- s.name = 'maillinks'
5
- s.version = '0.1.5'
5
+ s.name = PROGNAME
6
+ s.version = VERSION
6
7
  s.date = Date.today.strftime('%Y-%m-%d')
7
- s.summary = "runtime requirements, URLs better parsed, because the whole Quoted Printable decoding is done correctly, now."
8
+ s.summary = "Documentation in HTML formatted. Alternative Browsers allowed."
8
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"
9
- s.authors = ["Michael Uplawski"]
10
- s.email = 'michael.uplawski@uplawski.eu'
11
- s.files = %w~maillinks~.collect{|f| 'bin/' << f} + %w~constants.rb file_checking.rb log.conf logging.rb maillinks.rb translating.rb translations ~.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.homepage = 'http://rubygems.org'
13
- s.requirements = 'Linux, text-browser W3M'
14
- s.add_runtime_dependency 'nokogiri', '~> 1.8', '>= 1.8.2'
10
+ s.authors = AUTHORS
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}
13
+ s.homepage = 'https://www.uplawski.eu/software'
14
+ s.requirements = 'Linux, one of the browsers Dillo, W3M, Lynx, Brave-browser or Firefox'
15
+ s.add_runtime_dependency 'nokogiri', '~> 1.19', '>= 1.19.0'
15
16
  s.add_runtime_dependency 'escape', '~> 0.0', '>= 0.0.4'
16
- s.add_runtime_dependency 'mail', '~> 2.7', '>= 2.7.0'
17
+ s.add_runtime_dependency 'mail', '~> 2.9', '>= 2.9.0'
17
18
  s.executables = 'maillinks'
18
- s.license = 'GPL-3'
19
- s.required_ruby_version = '>= 2.1.2'
19
+ s.license = 'Nonstandard'
20
+ s.required_ruby_version = '>= 4.0'
21
+ s.metadata = {
22
+ "homepage_uri" => 'https://www.uplawski.eu/software/',
23
+ "documentation_uri" => 'https://www.uplawski.eu/software/maillinks/maillinks.html'
24
+ }
20
25
  end
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: maillinks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Uplawski
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2021-01-07 00:00:00.000000000 Z
10
+ date: 2026-04-28 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: nokogiri
@@ -16,20 +15,20 @@ dependencies:
16
15
  requirements:
17
16
  - - "~>"
18
17
  - !ruby/object:Gem::Version
19
- version: '1.8'
18
+ version: '1.19'
20
19
  - - ">="
21
20
  - !ruby/object:Gem::Version
22
- version: 1.8.2
21
+ version: 1.19.0
23
22
  type: :runtime
24
23
  prerelease: false
25
24
  version_requirements: !ruby/object:Gem::Requirement
26
25
  requirements:
27
26
  - - "~>"
28
27
  - !ruby/object:Gem::Version
29
- version: '1.8'
28
+ version: '1.19'
30
29
  - - ">="
31
30
  - !ruby/object:Gem::Version
32
- version: 1.8.2
31
+ version: 1.19.0
33
32
  - !ruby/object:Gem::Dependency
34
33
  name: escape
35
34
  requirement: !ruby/object:Gem::Requirement
@@ -56,20 +55,20 @@ dependencies:
56
55
  requirements:
57
56
  - - "~>"
58
57
  - !ruby/object:Gem::Version
59
- version: '2.7'
58
+ version: '2.9'
60
59
  - - ">="
61
60
  - !ruby/object:Gem::Version
62
- version: 2.7.0
61
+ version: 2.9.0
63
62
  type: :runtime
64
63
  prerelease: false
65
64
  version_requirements: !ruby/object:Gem::Requirement
66
65
  requirements:
67
66
  - - "~>"
68
67
  - !ruby/object:Gem::Version
69
- version: '2.7'
68
+ version: '2.9'
70
69
  - - ">="
71
70
  - !ruby/object:Gem::Version
72
- version: 2.7.0
71
+ version: 2.9.0
73
72
  description: Marks in an email HTMl-links and creates a list of all links at the bottom
74
73
  of the mail-text. Best used with the Mutt MUA
75
74
  email: michael.uplawski@uplawski.eu
@@ -83,19 +82,18 @@ files:
83
82
  - doc/man/maillinks.1.gz
84
83
  - doc/pdf/maillinks.pdf
85
84
  - doc/rst/maillinks.rst
85
+ - lib/basic_logging.rb
86
+ - lib/color_output.rb
86
87
  - lib/constants.rb
87
88
  - lib/file_checking.rb
88
- - lib/log.conf
89
- - lib/logging.rb
90
89
  - lib/maillinks.rb
91
- - lib/translating.rb
92
- - lib/translations
93
90
  - maillinks.gemspec
94
- homepage: http://rubygems.org
91
+ homepage: https://www.uplawski.eu/software
95
92
  licenses:
96
- - GPL-3
97
- metadata: {}
98
- post_install_message:
93
+ - Nonstandard
94
+ metadata:
95
+ homepage_uri: https://www.uplawski.eu/software/
96
+ documentation_uri: https://www.uplawski.eu/software/maillinks/maillinks.html
99
97
  rdoc_options: []
100
98
  require_paths:
101
99
  - lib
@@ -103,17 +101,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
103
101
  requirements:
104
102
  - - ">="
105
103
  - !ruby/object:Gem::Version
106
- version: 2.1.2
104
+ version: '4.0'
107
105
  required_rubygems_version: !ruby/object:Gem::Requirement
108
106
  requirements:
109
107
  - - ">="
110
108
  - !ruby/object:Gem::Version
111
109
  version: '0'
112
110
  requirements:
113
- - Linux, text-browser W3M
114
- rubygems_version: 3.2.0.rc.2
115
- signing_key:
111
+ - Linux, one of the browsers Dillo, W3M, Lynx, Brave-browser or Firefox
112
+ rubygems_version: 4.0.10
116
113
  specification_version: 4
117
- summary: runtime requirements, URLs better parsed, because the whole Quoted Printable
118
- decoding is done correctly, now.
114
+ summary: Documentation in HTML formatted. Alternative Browsers allowed.
119
115
  test_files: []