flnews_post_proc 1.45 → 1.48
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +8 -8
- data/bin/flnews_post_proc +1 -1
- data/lib/basic_logging.rb +40 -8
- data/lib/body.rb +7 -3
- data/lib/configuration.rb +6 -3
- data/lib/flnews_post_proc.rb +1 -2
- data/lib/headers.rb +4 -5
- data/lib/newsgroups.rb +5 -6
- data/lib/version.rb +3 -2
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a019c52dac602a5b00c71131e8b44a61769604a08035b7afad305a27c5d43a0
|
4
|
+
data.tar.gz: 7f5a69f62df2a18fefe9f0f5f499d7960d40b751b4bda67f26a88f91034ac941
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fe1d5fee2fffc214f8aa96b34e4886b3c2e7b16a71dd2ac99b8df214528d53c43df8b425fe4b21d4edf58e691e6cd5f497e09ed12a81129dd0f0e883fcf9ab76
|
7
|
+
data.tar.gz: 40f0b45424e01cc6b034aeeb4a7729bb0a499e231eb0001a60d762e4f1952964090dacda102fb87215ed66786e7e2887c471c95cc930018b469df669d16915b1
|
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
|
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,6 @@ self.extend(BasicLogging)
|
|
32
33
|
|
33
34
|
msg = PROGNAME.dup << ' ' << PROGVERSION << ' starting'
|
34
35
|
msg = "–––––– " << msg << " ––––––"
|
35
|
-
|
36
36
|
info msg
|
37
37
|
# Get a configuration
|
38
38
|
config = Configuration::instance
|
data/lib/basic_logging.rb
CHANGED
@@ -48,26 +48,30 @@ 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
|
-
|
59
|
-
|
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
|
|
63
67
|
# set the log target
|
64
68
|
def set_target(tg)
|
65
|
-
if
|
66
|
-
@@target = nil
|
67
|
-
elsif tg.respond_to?(:to_io)
|
69
|
+
if tg.respond_to?(:to_io)
|
68
70
|
@@target = tg
|
69
71
|
elsif(!File::exist?(tg) || ( File.file?(tg) && File.writable?(tg) ) )
|
70
72
|
@@target = File.open(tg, 'w+')
|
73
|
+
elsif !tg || tg.respond_to?(:to_str) && tg.strip.empty?
|
74
|
+
@@target = nil
|
71
75
|
else
|
72
76
|
STDERR.puts __FILE__.dup << ': ERROR : target ' << tg << ' cannot be set'
|
73
77
|
STDERR.puts "Keeping old target " << @@target.inspect
|
@@ -91,22 +95,50 @@ 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
|
+
lock_target{ @@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
|
|
122
|
+
def lock_target(&block)
|
123
|
+
begin
|
124
|
+
if @@target.respond_to?(:flock)
|
125
|
+
@@target.flock(File::LOCK_EX)
|
126
|
+
block.call
|
127
|
+
@@target.flock(File::LOCK_UN)
|
128
|
+
elsif @@target.respond_to?(:to_io)
|
129
|
+
block.call
|
130
|
+
end
|
131
|
+
rescue => ex
|
132
|
+
STDERR.puts __FILE__.dup << ": ERROR : cannot lock target (" << ex.message << ")"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
104
136
|
# 1 format_log for all loggers.
|
105
137
|
def format_log(message, mlevel)
|
106
138
|
if @@target
|
107
139
|
# indicate if a registered class or the registered object of a class is calling.
|
108
140
|
name = self.class == Class ? self.name.dup << ' [class]' : self.class.name
|
109
|
-
@@target.puts '' << name << ' ' << mlevel.to_s << ' ' << Time.now.strftime("%H:%M:%S:%6N") << ': ' << message.gsub("\n", "\n |")
|
141
|
+
lock_target{@@target.puts '' << name << ' ' << mlevel.to_s << ' ' << Time.now.strftime("%H:%M:%S:%6N") << ': ' << message.gsub("\n", "\n |")}
|
110
142
|
end
|
111
143
|
end
|
112
144
|
end
|
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
|
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.
|
@@ -119,9 +119,13 @@ class Body
|
|
119
119
|
end
|
120
120
|
|
121
121
|
def join
|
122
|
-
return @lines.join("\r\n")
|
122
|
+
return @lines.join("\r\n") << "\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()'
|
@@ -115,12 +114,16 @@ class Configuration
|
|
115
114
|
if File::exist?(@config_file) && File::readable?(@config_file)
|
116
115
|
begin
|
117
116
|
@conf = YAML::load_file(@config_file)
|
117
|
+
|
118
118
|
@conf.transform_keys!{|k| k.to_sym}
|
119
119
|
@keys = @conf.keys
|
120
120
|
clevel = @conf[:LOG_LEVEL]
|
121
121
|
set_level clevel
|
122
|
-
|
123
|
-
|
122
|
+
target_string = @conf[:DEBUG_LOG]
|
123
|
+
set_target (target_string == 'STDOUT' ? STDOUT : target_string)
|
124
|
+
# clear the log file.
|
125
|
+
clear_log
|
126
|
+
debug('log target and -level set: ' << @@log_level.to_s << ', ' << target_string)
|
124
127
|
rescue Exception => ex
|
125
128
|
msg = ex.message
|
126
129
|
error msg
|
data/lib/flnews_post_proc.rb
CHANGED
@@ -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
|
109
|
-
ch =
|
107
|
+
if @config.CUSTOM_HEADERS
|
108
|
+
ch = @config.CUSTOM_HEADERS
|
110
109
|
debug('setting custom headers : ' << ch.inspect)
|
111
|
-
|
110
|
+
@config.CUSTOM_HEADERS.each do |pair|
|
112
111
|
ch = pair.split(':')
|
113
112
|
hn = ch[0].strip
|
114
113
|
hv = ch[1].strip
|
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 =
|
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 =
|
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 =
|
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,9 @@
|
|
14
14
|
=end
|
15
15
|
|
16
16
|
PROGNAME = 'flnews_post_proc'
|
17
|
-
PROGVERSION = "1.
|
17
|
+
PROGVERSION = "1.48"
|
18
18
|
AUTHORS = "Michael Uplawski"
|
19
19
|
EMAIL = "michael.uplawski@uplawski.eu"
|
20
20
|
YEARS = "2023 - 2024"
|
21
|
-
SUMMARY = "
|
21
|
+
SUMMARY = "\tConcurrent access to the log file\n\tLog cleared upon setting log target"
|
22
|
+
SUMMARY << "\n\t\"STDOUT\" allowed as log target"
|
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.
|
4
|
+
version: '1.48'
|
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
|
+
date: 2024-05-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: diffy
|
@@ -82,8 +82,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
82
82
|
- !ruby/object:Gem::Version
|
83
83
|
version: '0'
|
84
84
|
requirements: []
|
85
|
-
rubygems_version: 3.
|
85
|
+
rubygems_version: 3.5.3
|
86
86
|
signing_key:
|
87
87
|
specification_version: 4
|
88
|
-
summary:
|
88
|
+
summary: Concurrent access to the log file Log cleared upon setting log target "STDOUT"
|
89
|
+
allowed as log target
|
89
90
|
test_files: []
|