flnews_post_proc 1.45 → 1.46

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.

Potentially problematic release.


This version of flnews_post_proc might be problematic. Click here for more details.

checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c48262d6fc3031346ffa1e2b528e11a696cef83b6d7c64fa98cdef444cf60247
4
- data.tar.gz: 12e53f1d88d613d14671ed06f03c0e65ca5f438088c85a66c22d3e37beec9b61
3
+ metadata.gz: a8f98e3bc6d688a4ee18fd913ee8f04fcc63115dfe50f2ae52f1d7814b5ffb58
4
+ data.tar.gz: 2193f2432974be939df1ae1d151a5aaa6c37808c76144ad779ccc1371ab0b379
5
5
  SHA512:
6
- metadata.gz: f1845950986bcb9919a4ad353c4913a9fca9427f2387bb8a4cbe7b1968eaf26f35d837f331dd9d3f9a1ab5c49b8e9a49d7868f89902c7b9f427d2592e73dc607
7
- data.tar.gz: f87ff6d5bd9462ebf3988b23482b64d6bb3d7ced99fbeecb06cc6c271392b65b7d8a510cd69e7e83c6792775ffbceb6e6dc1a6313b0bb2abd335752f508655ba
6
+ metadata.gz: d2f018b1861d3255fcf76a673c4f3b3af6ad7e77d05d245bdf2395bba6d45a1be582c6937c7d12ca766dfc7911c3c0b9a03ebce8e3bd0ada528808d1810c93e7
7
+ data.tar.gz: d8341b0b9d639d1fdfde99dadda0f786825f5e34c0c39264c691875bc6632435a5e2116a9dc76edcb5e8992718427790de6c0d5a8d07bdcb724caffa2eac9351
data/README.md CHANGED
@@ -93,14 +93,14 @@ some users may not always agree with the result and for arbitrary reasons:
93
93
  Custom headers may be defined in the configuration file for the program
94
94
  and will then be added to each outgoing post.
95
95
 
96
- * The Archive- and X-No-Archive headers are sometimes set to avoid that an
97
- article be saved and stays available to search-engines (Google, notably).
98
- Test- postings, for example, do probably not justify at all that they would
99
- be referenced in search results. The post-processor program can impose the
100
- Archive- and X-No-Archive header for all posts to certain newsgroups.
101
-
102
- **ATTN** As of 2024, the X-No-Archive has lost most of its utility and it
103
- is the decision of server operators to honor it or not.
96
+ * The Archive- and X-No-Archive headers are sometimes set to avoid that an
97
+ article be saved and stays available to search-engines (Google, notably).
98
+ Test- postings, for example, do probably not justify at all that they would
99
+ be referenced in search results. The post-processor program can impose the
100
+ Archive- and X-No-Archive header for all posts to certain newsgroups.
101
+
102
+ **ATTN** As of 2024, the header “X-No-Archive has lost most of its utility
103
+ and it is the decision of server operators to honor it or not.
104
104
 
105
105
  * If a news post contains many references to either other posts or Web
106
106
  pages, the text can be cluttered with URLs.
data/bin/flnews_post_proc CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/bin/env ruby
2
2
  #encoding: UTF-8
3
+
3
4
  =begin
4
5
  /***************************************************************************
5
6
  * ©2023-2024, Michael Uplawski <michael.uplawski@uplawski.eu> *
@@ -32,7 +33,7 @@ self.extend(BasicLogging)
32
33
 
33
34
  msg = PROGNAME.dup << ' ' << PROGVERSION << ' starting'
34
35
  msg = "–––––– " << msg << " ––––––"
35
-
36
+ clear_log
36
37
  info msg
37
38
  # Get a configuration
38
39
  config = Configuration::instance
data/lib/basic_logging.rb CHANGED
@@ -48,15 +48,19 @@ module BasicLogging
48
48
 
49
49
  # set the log level
50
50
  def set_level(lv)
51
- if lv.respond_to?(:to_str)
51
+ if lv.respond_to?(:to_str) && Levels.keys.include?(lv.strip.to_sym)
52
52
  lv = Levels[lv.to_sym]
53
+ elsif lv.respond_to?(:to_sym) && Levels.keys.include?(lv)
54
+ lv = Levels[lv]
53
55
  end
54
56
 
55
57
  if(!lv || (lv.respond_to?(:to_int) && lv >= DEBUG && lv <= FATAL) )
56
58
  @@log_level = lv
57
59
  else
58
- STDERR.puts __FILE__.dup << ": ERROR : invalid log level \"" << lv.to_s << "\""
59
- STDERR.puts "Keepinng old log level " << Levels.keys.detect {| k| Levels[k] == @@log_level}.to_s
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
60
64
  end
61
65
  end
62
66
 
@@ -91,13 +95,27 @@ module BasicLogging
91
95
  end
92
96
  end
93
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
+ @@target.truncate(0)
110
+ end
111
+ end
112
+
94
113
  alias :debug :log
95
114
  alias :info :log
96
115
  alias :warn :log
97
116
  alias :error :log
98
117
  alias :fatal :log
99
118
 
100
- attr_reader :target, :log_level
101
119
 
102
120
  private
103
121
 
data/lib/body.rb CHANGED
@@ -87,7 +87,7 @@ class Body
87
87
  i = i.next
88
88
  line = @lines[i]
89
89
  end
90
- # check if there is a citation, at all
90
+ # check if there is a quote, at all
91
91
  if(line.start_with?('>'))
92
92
  debug("\tfound intro " << ointro)
93
93
  # variables are part of the $intro.
@@ -121,7 +121,11 @@ class Body
121
121
  def join
122
122
  return @lines.join("\r\n")
123
123
  end
124
-
124
+ # ------->
125
+ # TODO : Concentrate all URL/URI munging functionality in 1 or 2 helper
126
+ # classes, e.g. Body::News and Body::Http
127
+ # <------
128
+
125
129
  # Verify and possibly correct links in the post.
126
130
  # Simple.
127
131
  def handle_urls()
data/lib/configuration.rb CHANGED
@@ -25,7 +25,6 @@ class Configuration
25
25
  include Singleton
26
26
  include BasicLogging
27
27
 
28
- self.extend(BasicLogging)
29
28
 
30
29
  def initialize()
31
30
  debug 'Configuration::initialize()'
@@ -114,7 +113,10 @@ class Configuration
114
113
  def read_config
115
114
  if File::exist?(@config_file) && File::readable?(@config_file)
116
115
  begin
116
+ puts "config_file is " << @config_file
117
117
  @conf = YAML::load_file(@config_file)
118
+ puts 'load_file'
119
+
118
120
  @conf.transform_keys!{|k| k.to_sym}
119
121
  @keys = @conf.keys
120
122
  clevel = @conf[:LOG_LEVEL]
@@ -29,11 +29,10 @@ $LN = "\r\n"
29
29
  # The main application class.
30
30
  # Does it.
31
31
  class PostProcessor
32
- # class-level configuration object
33
- @@config = Configuration.instance
34
32
  include BasicLogging
35
33
 
36
34
  def initialize(article_text)
35
+ @config = Configuration.instance
37
36
  # for simplicity.
38
37
  # separate the headers and the body.
39
38
  debug ' initializing headers'
data/lib/headers.rb CHANGED
@@ -20,13 +20,12 @@ require_relative 'newsgroups'
20
20
  # an object of this class represents the headers of a news-article
21
21
 
22
22
  class Headers
23
- # class-level configuration object
24
- @@config = Configuration.instance
25
23
  include BasicLogging
26
24
 
27
25
  # read the headers from the article
28
26
  def initialize(article_text)
29
27
 
28
+ @config = Configuration.instance
30
29
  line = nil
31
30
  # transform the article to an array.
32
31
  debug('before split, article_text is : ' << article_text)
@@ -105,10 +104,10 @@ class Headers
105
104
  @headers["X-No-Archive".to_sym] = no_archive
106
105
  @headers["Archive".to_sym] = 'no'
107
106
  end
108
- if @@config.CUSTOM_HEADERS
109
- ch = @@config.CUSTOM_HEADERS
107
+ if @config.CUSTOM_HEADERS
108
+ ch = @config.CUSTOM_HEADERS
110
109
  debug('setting custom headers : ' << ch.inspect)
111
- @@config.CUSTOM_HEADERS.each do |pair|
110
+ @config.CUSTOM_HEADERS.each do |pair|
112
111
  ch = pair.split(':')
113
112
  hn = ch[0].strip
114
113
  hv = ch[1].strip
@@ -0,0 +1,221 @@
1
+ #!/bin/env ruby
2
+ #encoding: UTF-8
3
+ =begin
4
+ /***************************************************************************
5
+ * 2023-2024, 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
+ require 'io/wait'
18
+ #
19
+ # Simplified logging.
20
+ # See example code at the bottom of this file.
21
+ # Execute this file to see the output.
22
+ module BasicLogging
23
+
24
+ DEBUG = 0
25
+ INFO = 1
26
+ WARN = 2
27
+ ERROR = 3
28
+ FATAL = 4
29
+ UNKNOWN = nil
30
+
31
+ # this is mainly for the translation of method calls into log levels
32
+ Levels = {:debug => DEBUG, :info => INFO, :warn => WARN, :error => ERROR,
33
+ :fatal => FATAL, :unknown => UNKNOWN}
34
+
35
+ @@log_level = UNKNOWN
36
+ @@log_target = STDOUT
37
+ @@muted = []
38
+
39
+ # do not log, if caller is obj (class or instance)
40
+ def self.mute(obj)
41
+ name = obj.class == Class ? obj.name.dup : obj.class.name
42
+ @@muted << name
43
+ end
44
+
45
+ # Log, if caller is obj (class or instance)
46
+ def self.unmute(obj)
47
+ name = obj.class == Class ? obj.name.dup : obj.class.name
48
+ if @@muted.include?(name)
49
+ @@muted.delete(name)
50
+ end
51
+ end
52
+
53
+ def self.is_muted?(obj)
54
+ name = obj.class == Class ? obj.name.dup : obj.class.name
55
+ @@muted.include?(name)
56
+ end
57
+
58
+ # set the log level
59
+ def set_level(lv)
60
+ # String – like 'debug' – or symbol – like :debug?
61
+ if lv
62
+ if lv.respond_to?(:to_str)
63
+ lv = lv.downcase.to_sym
64
+ # integer or nil
65
+ lv = Levels[lv]
66
+ elsif lv.respond_to?(:to_sym) && Levels.keys.include?(lv)
67
+ # integer or nil
68
+ lv = Levels[lv]
69
+ else
70
+ lv = nil
71
+ end
72
+ end
73
+ # set level to Integer or nil
74
+ if(!lv || (lv.respond_to?(:to_int) && lv >= DEBUG && lv <= FATAL) )
75
+ @@log_level = lv
76
+ else
77
+ STDERR.puts __FILE__.dup << ": ERROR : invalid log level \"" << lv.to_s << "\""
78
+ STDERR.puts "Keepinng old log level " << Levels.keys.detect {| k| Levels[k] == @@log_level}.to_s
79
+ end
80
+ end
81
+
82
+ # set the log target
83
+ def set_target(tg)
84
+ if !tg || tg.respond_to?(:to_str) && tg.strip.empty?
85
+ @@log_target = nil
86
+ elsif tg.respond_to?(:to_io) && tg.wait_writable
87
+ @@log_target = tg
88
+ elsif(!File::exist?(tg) || ( File.file?(tg) && File.writable?(tg) ) )
89
+ @@log_target = File.open(tg, 'w+')
90
+ else
91
+ STDERR.puts __FILE__.dup << ': ERROR : target ' << tg << ' cannot be set'
92
+ STDERR.puts "Keeping old target " << @@log_target.inspect
93
+ return
94
+ end
95
+ end
96
+
97
+ # Output of log messages, depending on the log level set for the calling class
98
+ # and the name of the alias method which is actually called.
99
+ def log(message)
100
+ if !BasicLogging.is_muted?(self)
101
+ # how has this method been called?
102
+ mlevel = __callee__
103
+ if Levels.has_key?(mlevel) && Levels[mlevel] <= FATAL
104
+ # output only for levels equal or above the value that corresponds to
105
+ # the calling alias.
106
+ if @@log_level && Levels[mlevel] >= @@log_level
107
+ format_log( message, mlevel)
108
+ end
109
+ else
110
+ STDERR.puts __FILE__.dup << ": ERROR : invalid log level \"" << mlevel.to_s << "\""
111
+ end
112
+ end
113
+ end
114
+
115
+ def target
116
+ @@log_target.path if @@log_target
117
+ end
118
+
119
+ def level
120
+ @@log_level.to_s if @@log_level
121
+ end
122
+
123
+ # Clear the log (-file)
124
+ def clear_log
125
+ if @@log_target && @@log_target.respond_to?(:truncate)
126
+ File::truncate(@@log_target, 0)
127
+ end
128
+ end
129
+
130
+ alias :debug :log
131
+ alias :info :log
132
+ alias :warn :log
133
+ alias :error :log
134
+ alias :fatal :log
135
+
136
+
137
+ private
138
+
139
+ # 1 format_log for all loggers.
140
+ def format_log(message, mlevel)
141
+ if @@log_target
142
+ # indicate if a registered class or the registered object of a class is calling.
143
+ name = self.class == Class ? self.name.dup << ' [class]' : self.class.name
144
+ str = '' << name << ' ' << mlevel.to_s << ' ' << Time.now.strftime("%H:%M:%S:%6N") << ': ' << message.gsub("\n", "\n |")
145
+ @@log_target.puts str
146
+ end
147
+ end
148
+ end
149
+ #---------test: execute file----------
150
+ if $0 == __FILE__
151
+ Array.extend(BasicLogging)
152
+ Array.set_level("info")
153
+ Array.info('TEST')
154
+ ar = Array.new
155
+ ar.extend(BasicLogging)
156
+ # --- no output :
157
+ l = __LINE__
158
+ ar.debug(l.next.to_s << ': debug-test 0')
159
+ # output
160
+ ar.set_level(:debug)
161
+ l = __LINE__
162
+ ar.debug(l.next.to_s << ': debug-test 1')
163
+
164
+ obj = Object.new
165
+ obj.extend(BasicLogging)
166
+ obj.set_level(BasicLogging::DEBUG)
167
+ puts "--------debug-----------"
168
+ obj.debug('debug')
169
+ obj.info('info')
170
+ obj.warn('warn')
171
+ obj.error('error')
172
+ obj.fatal('fatal')
173
+ puts "--------info-----------"
174
+ obj.set_level("info")
175
+ obj.debug('debug')
176
+ obj.info('info')
177
+ obj.warn('warn')
178
+ obj.error('error')
179
+ obj.fatal('fatal')
180
+ puts "--------fatal-----------"
181
+ obj.set_level("fatal")
182
+ obj.debug('debug')
183
+ obj.info('info')
184
+ obj.warn('warn')
185
+ obj.error('error')
186
+ obj.fatal('fatal')
187
+ puts "--------UNKNOWN-----------"
188
+ obj.set_level(nil)
189
+ obj.debug('debug')
190
+ obj.info('info')
191
+ obj.warn('warn')
192
+ obj.error('error')
193
+ obj.fatal('fatal')
194
+ puts " ------ Output into file ----"
195
+ obj.set_target "/tmp/test_log.log"
196
+ puts " ------ INFO -----------"
197
+ obj.set_level BasicLogging::INFO
198
+ obj.info('info output')
199
+
200
+ obj.info('info output 2')
201
+ puts "---------- invalid -------"
202
+ obj.set_target(STDOUT)
203
+ obj.set_level "power"
204
+ begin
205
+ File.open("/tmp/invalid_log", 'r') do |f|
206
+ obj.set_target f
207
+ end
208
+ rescue Exception => er
209
+ obj.error "ERROR! " << er.message
210
+ end
211
+ puts "------------ muted -------"
212
+ BasicLogging::mute obj
213
+ puts "is muted? " << BasicLogging.is_muted?(obj).to_s
214
+ obj.info "test"
215
+ puts "--------- unmute ----"
216
+ BasicLogging::unmute obj
217
+ puts "is muted? " << BasicLogging.is_muted?(obj).to_s
218
+ obj.info "back again"
219
+ end
220
+
221
+ # EOF
data/lib/newsgroups.rb CHANGED
@@ -20,11 +20,10 @@ require_relative 'configuration'
20
20
  require_relative 'basic_logging'
21
21
 
22
22
  class Newsgroups
23
- # class-level configuration object
24
- @@config = Configuration.instance
25
- include BasicLogging
26
23
 
24
+ include BasicLogging
27
25
  def initialize(groups)
26
+ @config = Configuration.instance
28
27
  @groups = groups.split(',')
29
28
  debug('set signature, intro, no_archive')
30
29
  # set details for this post
@@ -50,7 +49,7 @@ class Newsgroups
50
49
  # only one group.
51
50
  group = @groups[0]
52
51
  # all configured intro-lines.
53
- gintros = @@config.GROUP_INTROS
52
+ gintros = @config.GROUP_INTROS
54
53
 
55
54
  if gintros && gintros.respond_to?(:to_hash)
56
55
  # find the intro for the group.
@@ -93,7 +92,7 @@ class Newsgroups
93
92
  @signature = nil
94
93
  # 1 group
95
94
  group = @groups[0]
96
- gsigs = @@config.GROUP_SIGS
95
+ gsigs = @config.GROUP_SIGS
97
96
 
98
97
  if gsigs && gsigs.respond_to?(:to_hash)
99
98
  # find the signature for the group
@@ -124,7 +123,7 @@ class Newsgroups
124
123
  # define the no_archive header.
125
124
  def set_no_archive
126
125
  @no_archive = nil
127
- xgs = @@config.NO_ARCHIVE_GROUPS
126
+ xgs = @config.NO_ARCHIVE_GROUPS
128
127
  if xgs && !xgs.empty? && xgs.detect {|g| @groups[0].match(g) }
129
128
  debug("setting no_archive")
130
129
  @no_archive = 'yes'
data/lib/version.rb CHANGED
@@ -14,8 +14,8 @@
14
14
  =end
15
15
 
16
16
  PROGNAME = 'flnews_post_proc'
17
- PROGVERSION = "1.45"
17
+ PROGVERSION = "1.46"
18
18
  AUTHORS = "Michael Uplawski"
19
19
  EMAIL = "michael.uplawski@uplawski.eu"
20
20
  YEARS = "2023 - 2024"
21
- SUMMARY = "Bugfix: URLs exclude punctuation and others at the end."
21
+ SUMMARY = "Logging modul: unused functionality corrected."
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flnews_post_proc
3
3
  version: !ruby/object:Gem::Version
4
- version: '1.45'
4
+ version: '1.46'
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Uplawski
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-11 00:00:00.000000000 Z
11
+ date: 2024-05-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: diffy
@@ -56,6 +56,7 @@ files:
56
56
  - lib/flnews_post_proc.conf
57
57
  - lib/flnews_post_proc.rb
58
58
  - lib/headers.rb
59
+ - lib/new_basic_logging.rb
59
60
  - lib/newsgroups.rb
60
61
  - lib/override.rb
61
62
  - lib/ruby_dlg
@@ -82,8 +83,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
83
  - !ruby/object:Gem::Version
83
84
  version: '0'
84
85
  requirements: []
85
- rubygems_version: 3.4.20
86
+ rubygems_version: 3.5.3
86
87
  signing_key:
87
88
  specification_version: 4
88
- summary: 'Bugfix: URLs exclude punctuation and others at the end.'
89
+ summary: 'Logging modul: unused functionality corrected.'
89
90
  test_files: []