flnews_post_proc 1.7 → 1.40
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/README.md +28 -35
- data/bin/flnews_post_proc +12 -56
- data/doc/html/flnews_post_proc.html +364 -52
- data/doc/{fr/html/flnews_post_proc.html → html/flnews_post_proc_fr.html} +19 -22
- data/doc/man/flnews_post_proc.1.gz +0 -0
- data/doc/man/flnews_post_proc_fr.1.gz +0 -0
- data/doc/pdf/flnews_post_proc.pdf +0 -0
- data/doc/pdf/flnews_post_proc_fr.pdf +0 -0
- data/doc/rst/flnews_post_proc.rst +26 -28
- data/doc/{fr/rst/flnews_post_proc.rst → rst/flnews_post_proc_fr.rst} +18 -21
- data/lib/basic_logging.rb +8 -40
- data/lib/body.rb +35 -129
- data/lib/configuration.rb +8 -15
- data/lib/flnews_post_proc.conf +6 -7
- data/lib/flnews_post_proc.rb +4 -5
- data/lib/headers.rb +13 -37
- data/lib/newsgroups.rb +17 -35
- data/lib/override.rb +2 -2
- data/lib/ruby_dlg +83 -86
- data/lib/version.rb +2 -3
- data/lib/whiptail_dlg +2 -7
- data/lib/yad_dlg +11 -12
- data/lib/zenity_dlg +7 -8
- metadata +9 -30
- data/doc/fr/man/flnews_post_proc.1.gz +0 -0
- data/doc/fr/pdf/flnews_post_proc.pdf +0 -0
- data/lib/_quoting_style_regexp +0 -2
@@ -50,8 +50,7 @@ some users may not always agree with the result and for arbitrary reasons:
|
|
50
50
|
would like to replace it against another, based on the newsgroup you are
|
51
51
|
about to post to.
|
52
52
|
The post-processor program sets specific signatures as configured for one
|
53
|
-
or several newsgroups.
|
54
|
-
picked randomly from a file, containing several signatures.
|
53
|
+
or several newsgroups.
|
55
54
|
|
56
55
|
* Some custom headers may serve to convey additional information to
|
57
56
|
interested readers of your post, like GnuPG key IDs, your language skills
|
@@ -61,15 +60,14 @@ some users may not always agree with the result and for arbitrary reasons:
|
|
61
60
|
Custom-headers may be defined in the configuration file for the program
|
62
61
|
and will then be added to each outgoing post.
|
63
62
|
|
64
|
-
* The
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
The post-processor program can impose
|
69
|
-
newsgroups.
|
63
|
+
* The X-No-Archive header is sometimes set to avoid that an article be
|
64
|
+
saved and stays available to search-engines (Google, notably). Test-
|
65
|
+
postings, for example, do probably not justify at all that they would be
|
66
|
+
referenced in search-results.
|
67
|
+
The post-processor program can impose the X-No-Archive header for all
|
68
|
+
posts to certain newsgroups.
|
70
69
|
|
71
|
-
**ATTN**
|
72
|
-
and it is the decision of server operators to honor it or not.
|
70
|
+
**ATTN** Since 2024, this header might no longer serve any purpose.
|
73
71
|
|
74
72
|
* If a news post contains many references to either other posts or Web
|
75
73
|
pages, the text can be cluttered with URLs.
|
@@ -93,8 +91,8 @@ have not yet been set in the configuration.
|
|
93
91
|
* Signatures, as set in the configuration **can be ignored**. Either
|
94
92
|
a default signature will appear as set in flnews or none.
|
95
93
|
* Custom Headers, if configured, can be **omitted**.
|
96
|
-
* The
|
97
|
-
|
94
|
+
* The X-No-Archive header, if set for the current newsgroup, **can be
|
95
|
+
ignored**.
|
98
96
|
* Logging can be **switched off**, if set.
|
99
97
|
|
100
98
|
Pushing Esc or the cancle-button of the dialog interrupts the process, flnews
|
@@ -168,10 +166,7 @@ categories:
|
|
168
166
|
EXAMPLE: alt.test: "Thus spoke %fup_name% on that baleful %fup_date%:"
|
169
167
|
|
170
168
|
**GROUP_SIGS**
|
171
|
-
A signature line per Newsgroup
|
172
|
-
already formatted and separated by 1 empty line. The program will randomly pick
|
173
|
-
one signature from the list.
|
174
|
-
|
169
|
+
A signature line per Newsgroup.
|
175
170
|
ATTN! In multi line signatures, you have to use \\r\\n for line breaks.
|
176
171
|
|
177
172
|
CONTENT: A newsgroup or regexp per line, followed by a colon, a space and a String.
|
@@ -179,8 +174,6 @@ categories:
|
|
179
174
|
DEFAULT: As configured in flnews
|
180
175
|
|
181
176
|
EXAMPLE: alt.test: "Signature for alt.test\\r\\nsecond line"
|
182
|
-
|
183
|
-
EXAMPLE: comp.*: /home/[user]/.my_sigs
|
184
177
|
|
185
178
|
**CUSTOM_HEADERS**
|
186
179
|
Additional headers for the outgoing article
|
@@ -194,9 +187,9 @@ categories:
|
|
194
187
|
| - 'X-My-Header: nothing fancy'
|
195
188
|
| - 'X-Another-Header: care not!'
|
196
189
|
|
197
|
-
**
|
198
|
-
The newsgroups, where
|
199
|
-
|
190
|
+
**XNAY_GROUPS**
|
191
|
+
The newsgroups, where a header X-No-Archive: YES shall be set.
|
192
|
+
**ATTN** Since 2024, this header might no longer serve any purpose.
|
200
193
|
|
201
194
|
CONTENT: a dash and space, then a String, containing the name of the group or a regexp.
|
202
195
|
|
@@ -264,8 +257,12 @@ categories:
|
|
264
257
|
try to correct URLs. Even if URLs are identified as such, only a few
|
265
258
|
manipulations are attempted :
|
266
259
|
* Angular brackets '<' and '>' are added, if missing
|
260
|
+
* Article-references are prepended with "news:", if missing
|
267
261
|
* Slashes are added, if they are found missing after "http(s):"
|
268
262
|
|
263
|
+
ATTN! The program is unable to discern "mailto:" and "news:" references. If
|
264
|
+
neither is given, but '@' is present, "news:" is automatically prepended.
|
265
|
+
|
269
266
|
If the variable is not set, a value 'yes' is assumed.
|
270
267
|
|
271
268
|
CONTENT: One of YES, yes, NO, no, and other variations of case.
|
@@ -275,13 +272,14 @@ categories:
|
|
275
272
|
Example: ... I let you guess.
|
276
273
|
|
277
274
|
**OVERRIDE_CONFIG**
|
278
|
-
A Boolean constant. You can choose to override the following
|
279
|
-
options before an article is posted:
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
275
|
+
A Boolean constant. You can choose to override the following
|
276
|
+
configuration options before an article is posted:
|
277
|
+
GROUP_SIGS, XNAY_GROUPS, CUSTOM_HEADERS and DEBUG_LOG.
|
278
|
+
A dialog may be displayed which allows you to disable any of these
|
279
|
+
four options, so that the defaults from flnews prevail.
|
280
|
+
|
281
|
+
ATTN! Canceling the dialog or pushing the Esc-key does interrupt
|
282
|
+
the process. Flnews will not post the article.
|
285
283
|
|
286
284
|
Set this option to no, NO or similar to disable the dialog.
|
287
285
|
|
@@ -73,19 +73,16 @@ et ce pour des raisons arbitraires :
|
|
73
73
|
Ces entêtes, – Custom-Headers – peuvent être définis dans la configuration
|
74
74
|
du logiciel et vont être utilisées dans chaque article sortant.
|
75
75
|
|
76
|
-
*
|
77
|
-
d'
|
78
|
-
|
79
|
-
|
80
|
-
|
76
|
+
* L'entête « X-No-Archive » est parfois utilisé afin d'éviter l'archivage
|
77
|
+
d'un article. Il ne devrait par conséquence pas être trouvé par les moteurs
|
78
|
+
de recherche ( Google notamment ). Les articles dans les groupes de test, par
|
79
|
+
exemple, ne valent probablement pas qu'on les trouve parmi les résultats des
|
80
|
+
recherches.
|
81
81
|
|
82
82
|
Avec flnews_post_proc vous pouvez décider et imposer que vos articles dans
|
83
|
-
certains newsgroups contiendront d'office
|
84
|
-
**X-No-Archive: Yes**.
|
83
|
+
certains newsgroups contiendront d'office une entête **X-No-Archive: Yes**.
|
85
84
|
|
86
|
-
**
|
87
|
-
utilité. Les opérateurs des serveurs peuvent décider s'ils veulent le prendre
|
88
|
-
en considération ou non.
|
85
|
+
**ATTN** Depuis l'année 2024, cet entête n'a probablement plus de fonction.
|
89
86
|
|
90
87
|
* Certains messages mentionnent d'autres articles ou des URLs de pages Web.
|
91
88
|
S'ils sont nombreux, ces références peuvent déranger la lecture à cause de
|
@@ -115,8 +112,7 @@ des options, qui ne l'ont pas été auparavant :
|
|
115
112
|
|
116
113
|
* Entêtes supplémentaires, si définis, peuvent rester absentes de l'article.
|
117
114
|
|
118
|
-
*
|
119
|
-
peuvent être ignorés.
|
115
|
+
* L'entête X-No-Archive, si prévu pour le newsgroup choisi, peut être ignoré.
|
120
116
|
|
121
117
|
* L'auto correction de URLs et références à d'autres articles peut être
|
122
118
|
désactivé.
|
@@ -222,9 +218,9 @@ variables définis dans ce fichier peuvent être classées en deux catégories :
|
|
222
218
|
| - 'X-My-Header: nothing fancy'
|
223
219
|
| - 'X-Another-Header: care not!'
|
224
220
|
|
225
|
-
**
|
226
|
-
Les newsgroups, où
|
227
|
-
|
221
|
+
**XNAY_GROUPS**
|
222
|
+
Les newsgroups, où une entête X-No-Arcive: YES doit être présent.
|
223
|
+
**ATTN** Depuis l'année 2024, cet entête n'a probablement plus de fonction.
|
228
224
|
|
229
225
|
CONTENU : Un trait d'union et un espace, puis une chaîne de caractères,
|
230
226
|
contenant le nom du groupe ou une expression.
|
@@ -297,10 +293,11 @@ variables définis dans ce fichier peuvent être classées en deux catégories :
|
|
297
293
|
|
298
294
|
**VFY_URLS**
|
299
295
|
Une constante booléen. Elle détermine si le programme doit essayer de corriger
|
300
|
-
des
|
296
|
+
des URIs. Même si les URIs sont identifiables, seulement quelques manipulations
|
301
297
|
sont temptées :
|
302
298
|
|
303
299
|
* '<' et '>' sont ajoutés, si manquants
|
300
|
+
* "news:" est ajouté au début des références à d'autres articles
|
304
301
|
* Des slashes sont insérés, s'ils manquent après "http(s):"
|
305
302
|
|
306
303
|
ATTN! Le programme ne peut pas différencier entre "mailto:" et "news:". Si ni l'un
|
@@ -315,11 +312,11 @@ variables définis dans ce fichier peuvent être classées en deux catégories :
|
|
315
312
|
EXEMPLE: No
|
316
313
|
|
317
314
|
**OVERRIDE_CONFIG**
|
318
|
-
Une constante booléenne. Vous pouvez décider d'ignorer les options
|
319
|
-
avant qu'un article est posté :
|
320
|
-
VFY_URLS et DEBUG_LOG.
|
321
|
-
|
322
|
-
flnews, vont donc prévaloir.
|
315
|
+
Une constante booléenne. Vous pouvez décider d'ignorer les options
|
316
|
+
suivantes avant qu'un article est posté :
|
317
|
+
GROUP_SIGS, XNAY_GROUPS, CUSTOM_HEADERS, VFY_URLS et DEBUG_LOG.
|
318
|
+
Un dialogue peut être affiché, qui permet la désactivation de chacune de ces
|
319
|
+
options. Les valeurs par défaut, définis pour flnews, vont donc prévaloir.
|
323
320
|
|
324
321
|
ATTN ! En poussant Esc ou le bouton « Annuler » du dialogue, vous interrompez
|
325
322
|
le programme et flnews ne va rien envoyer.
|
data/lib/basic_logging.rb
CHANGED
@@ -48,30 +48,26 @@ 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)
|
52
52
|
lv = Levels[lv.to_sym]
|
53
|
-
elsif lv.respond_to?(:to_sym) && Levels.keys.include?(lv)
|
54
|
-
lv = Levels[lv]
|
55
53
|
end
|
56
54
|
|
57
55
|
if(!lv || (lv.respond_to?(:to_int) && lv >= DEBUG && lv <= FATAL) )
|
58
56
|
@@log_level = lv
|
59
57
|
else
|
60
|
-
|
61
|
-
|
62
|
-
STDERR.puts msg
|
63
|
-
puts msg
|
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
|
64
60
|
end
|
65
61
|
end
|
66
62
|
|
67
63
|
# set the log target
|
68
64
|
def set_target(tg)
|
69
|
-
if tg.
|
65
|
+
if !tg || tg.strip.empty?
|
66
|
+
@@target = nil
|
67
|
+
elsif tg.respond_to?(:to_io)
|
70
68
|
@@target = tg
|
71
69
|
elsif(!File::exist?(tg) || ( File.file?(tg) && File.writable?(tg) ) )
|
72
70
|
@@target = File.open(tg, 'w+')
|
73
|
-
elsif !tg || tg.respond_to?(:to_str) && tg.strip.empty?
|
74
|
-
@@target = nil
|
75
71
|
else
|
76
72
|
STDERR.puts __FILE__.dup << ': ERROR : target ' << tg << ' cannot be set'
|
77
73
|
STDERR.puts "Keeping old target " << @@target.inspect
|
@@ -95,50 +91,22 @@ module BasicLogging
|
|
95
91
|
end
|
96
92
|
end
|
97
93
|
|
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
94
|
alias :debug :log
|
114
95
|
alias :info :log
|
115
96
|
alias :warn :log
|
116
97
|
alias :error :log
|
117
98
|
alias :fatal :log
|
118
99
|
|
100
|
+
attr_reader :target, :log_level
|
119
101
|
|
120
102
|
private
|
121
103
|
|
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
|
-
|
136
104
|
# 1 format_log for all loggers.
|
137
105
|
def format_log(message, mlevel)
|
138
106
|
if @@target
|
139
107
|
# indicate if a registered class or the registered object of a class is calling.
|
140
108
|
name = self.class == Class ? self.name.dup << ' [class]' : self.class.name
|
141
|
-
|
109
|
+
@@target.puts '' << name << ' ' << mlevel.to_s << ' ' << Time.now.strftime("%H:%M:%S:%6N") << ': ' << message.gsub("\n", "\n |")
|
142
110
|
end
|
143
111
|
end
|
144
112
|
end
|
data/lib/body.rb
CHANGED
@@ -1,64 +1,23 @@
|
|
1
1
|
#encoding: UTF-8
|
2
2
|
|
3
3
|
=begin
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
15
|
=end
|
16
16
|
|
17
17
|
require_relative 'basic_logging'
|
18
|
-
|
18
|
+
require_relative 'configuration'
|
19
19
|
|
20
|
-
|
21
|
-
# Endow the String class with a wrap function.
|
22
|
-
# This is not yet applicable to the message body, itself.
|
23
|
-
class String
|
24
|
-
include BasicLogging
|
25
|
-
public
|
26
|
-
# wraps at length, returns the result
|
27
|
-
def wrap! (length = WRAP_LENGTH, indent = 0)
|
28
|
-
max = length
|
29
|
-
|
30
|
-
line = 0
|
31
|
-
out = [""]
|
32
|
-
|
33
|
-
self.gsub!(/^\r\n/, "[rnrn]")
|
34
|
-
self.gsub!("\r\n", " ")
|
35
|
-
self.gsub!(" ", " ")
|
36
|
-
|
37
|
-
words = self.split(" ")
|
38
|
-
|
39
|
-
while !words.empty?
|
40
|
-
word = words.shift.strip
|
41
|
-
break if not word
|
42
|
-
if out[line].length + word.length > max
|
43
|
-
out[line].squeeze!(" ")
|
44
|
-
line += 1
|
45
|
-
out[line] = (line > 0 ? " " * indent : "")
|
46
|
-
end
|
47
|
-
out[line] << word + " "
|
48
|
-
end
|
49
|
-
out = out.join("\r\n")
|
50
|
-
out.gsub!("[rnrn]", "\r\n\r\n")
|
51
|
-
self.replace( out)
|
52
|
-
end
|
53
|
-
|
54
|
-
end
|
55
|
-
|
56
|
-
# An object of this class represents the body of a news-article.
|
57
|
-
# It processes the original text and changes some details:
|
58
|
-
# intro-lines
|
59
|
-
# signatures
|
60
|
-
# URI formats
|
61
|
-
# Footnotes (and/or a list of references) are created
|
20
|
+
# an object of this class represents the body of a news-article.
|
62
21
|
class Body
|
63
22
|
# a class-level configuration instance.
|
64
23
|
@@config = Configuration.instance
|
@@ -128,7 +87,7 @@ class Body
|
|
128
87
|
i = i.next
|
129
88
|
line = @lines[i]
|
130
89
|
end
|
131
|
-
# check if there is a
|
90
|
+
# check if there is a citation, at all
|
132
91
|
if(line.start_with?('>'))
|
133
92
|
debug("\tfound intro " << ointro)
|
134
93
|
# variables are part of the $intro.
|
@@ -140,13 +99,6 @@ class Body
|
|
140
99
|
# exchange original intro-line against the new one
|
141
100
|
@lines[@lines.index(ointro)] = intro.strip
|
142
101
|
# looked complicated because it is.
|
143
|
-
|
144
|
-
# keep this line for reference.
|
145
|
-
@intro = intro
|
146
|
-
else
|
147
|
-
wmsg = 'Text following the intro is not a citation!'
|
148
|
-
wmsg << "\n\tIntro will NOT be modified: \"#{ointro}\"!"
|
149
|
-
warn wmsg
|
150
102
|
end
|
151
103
|
end
|
152
104
|
end # fn.strip.empty?
|
@@ -159,7 +111,7 @@ class Body
|
|
159
111
|
# remove any signature(s) from
|
160
112
|
# the current article
|
161
113
|
sigpos = @lines.index('-- ')
|
162
|
-
debug('found signature
|
114
|
+
debug('found signature at position ' << sigpos) if sigpos
|
163
115
|
@lines = @lines.slice(0, sigpos ) if sigpos
|
164
116
|
debug('setting signature ' << signature) if signature
|
165
117
|
@lines << "-- " << signature if signature
|
@@ -167,29 +119,18 @@ class Body
|
|
167
119
|
end
|
168
120
|
|
169
121
|
def join
|
170
|
-
|
171
|
-
# replace ellipsis
|
172
|
-
new_body.force_encoding('utf-8').gsub!('...', '…')
|
173
|
-
return new_body
|
122
|
+
return @lines.join("\r\n")
|
174
123
|
end
|
175
|
-
|
176
|
-
# ------->
|
177
|
-
# TODO : Concentrate all URL/URI munging functionality in 1 or 2 helper
|
178
|
-
# classes, e.g. Body::News and Body::Http
|
179
|
-
# <------
|
180
|
-
|
124
|
+
|
181
125
|
# Verify and possibly correct links in the post.
|
182
126
|
# Simple.
|
183
|
-
def
|
127
|
+
def handle_urls()
|
184
128
|
# Determine here or elsewhere if URLs shall be verified.
|
185
|
-
# Default is no. nil or '' do qualify as default.
|
186
|
-
debug 'verify URLs ? ' << @@config.VFY_URLS.to_s
|
129
|
+
# Default is != no. nil or '' do qualify as default.
|
187
130
|
if @@config.VFY_URLS
|
188
|
-
debug 'verifying URLs'
|
189
131
|
@lines.each_with_index do | l, i |
|
190
132
|
# leave cited lines as they are.
|
191
133
|
if !l.start_with?( '>')
|
192
|
-
=begin Currently Unused
|
193
134
|
# IMPORTANT --------------------------------->
|
194
135
|
# IT IS HENCEFORTH PROHIBITED TO WRITE AN EMAIL-ADDRESS
|
195
136
|
# IN THE BODY OF A NEWS-POST AND TO NOT PREPEND IT WITH
|
@@ -199,9 +140,7 @@ class Body
|
|
199
140
|
# <----------------------------
|
200
141
|
|
201
142
|
# BUGFIX : Urls with @
|
202
|
-
|
203
|
-
new_line = handle_news(l) if !@intro || l.strip != @intro.strip
|
204
|
-
=end
|
143
|
+
new_line = handle_news(l)
|
205
144
|
# http(s)
|
206
145
|
if l.include?('http')
|
207
146
|
new_line = handle_http(l)
|
@@ -211,7 +150,7 @@ class Body
|
|
211
150
|
end # @lines.each_with_index
|
212
151
|
end # if verify
|
213
152
|
end
|
214
|
-
|
153
|
+
|
215
154
|
# extract URL or other stuff, if configured for footnotes,
|
216
155
|
def handle_references()
|
217
156
|
# a symbol or string to mark the beginning an ending of a future footnote.
|
@@ -229,8 +168,9 @@ class Body
|
|
229
168
|
# to the whole body, over multiple lines, if need be.
|
230
169
|
begin
|
231
170
|
ref = body.match(ref_rx )
|
232
|
-
debug("found reference " << ref.to_s << " (length: " << (ref ? ref.to_s.size.to_s : '0') << ")")
|
171
|
+
debug("found reference " << ref.to_s << " (length: " << (ref ? ref.to_s.size.to_s : '0') << ")")
|
233
172
|
if ref
|
173
|
+
debug('ref is ' << ref.to_s)
|
234
174
|
# ... This is some presentation thing and I think
|
235
175
|
# it works, too.
|
236
176
|
r = ref[0].gsub(/[ \t]+/, ' ').strip
|
@@ -240,11 +180,7 @@ class Body
|
|
240
180
|
body.gsub!(ref[0], format(@@config.REFERENCE_FORMAT, index.to_s ))
|
241
181
|
end
|
242
182
|
end until ref == nil
|
243
|
-
debug("all references found:\n" << references.join('\n'))
|
244
|
-
# re-wrap body
|
245
|
-
# ATTN! Does not work!
|
246
|
-
# body.wrap!(WRAP_LENGTH)
|
247
|
-
|
183
|
+
debug("all references found:\n" << references.join('\n'))
|
248
184
|
else
|
249
185
|
msg = 'The References Delimiter is the same in its reversed form.'
|
250
186
|
msg << "#{$LN}Cannot handle references or footnotes!"
|
@@ -256,40 +192,30 @@ class Body
|
|
256
192
|
body << $LN << @@config.REFERENCES_SEPARATOR << $LN
|
257
193
|
references.each_with_index do |r, i|
|
258
194
|
r = r.gsub(ref_delim, '').gsub(ref_delim.reverse,'')
|
259
|
-
|
260
|
-
r.strip!
|
261
|
-
debug 'reference ' << r
|
262
|
-
body << num << r << $LN
|
195
|
+
body << (i + 1 ).to_s << ") " << r.strip << $LN
|
263
196
|
end
|
264
|
-
else
|
265
|
-
debug('no refences found')
|
266
197
|
end
|
267
198
|
end
|
268
199
|
@lines = body.split($LN)
|
269
|
-
@encoding = body.encoding
|
270
200
|
end
|
271
201
|
private
|
272
202
|
|
273
203
|
# handle <news:..@...>
|
274
204
|
def handle_news(l)
|
275
205
|
# ... “Do not trust nobody!”
|
276
|
-
if l.include?('@') && ! l.include?('http:')
|
206
|
+
if l.include?('@') && ! l.include?('http:')
|
277
207
|
# And I forgot how this works. It does.
|
278
208
|
l.split.collect do |ele|
|
279
209
|
# angular brackets are there alright. Hurra.
|
280
210
|
url = ele.match(/\<(.*)\>/)
|
281
211
|
unless !url
|
282
212
|
debug(' with angular brackets: ' << url.inspect)
|
283
|
-
l = l.sub(url[1], 'news:' << url[1]) if !url[1].
|
213
|
+
l = l.sub(url[1], 'news:' << url[1]) if !url[1].include?('mailto')
|
284
214
|
else
|
285
215
|
url = ele.match(/\S+@(\.|[^\p{P}]+)\S+/)
|
286
216
|
if url
|
287
217
|
debug(' withOUT angular brackets: ' << url.inspect)
|
288
|
-
|
289
|
-
l.sub!(url[0], 'news:' << url[0] )
|
290
|
-
end
|
291
|
-
l.sub!('news:', '<news:')
|
292
|
-
l.sub!(url[0], url[0] << '>')
|
218
|
+
l = l.sub(url[0], '<news:' << url[0] << '>') if !url[0].include?('mailto')
|
293
219
|
end
|
294
220
|
end
|
295
221
|
end # url_strs = collect
|
@@ -301,16 +227,7 @@ class Body
|
|
301
227
|
def handle_http(l)
|
302
228
|
debug('handle http')
|
303
229
|
l_array = l.split
|
304
|
-
url_strs = l_array.collect
|
305
|
-
if ele.strip.include?('http') && ele.match(/https?:\S+/)
|
306
|
-
ele.lstrip!
|
307
|
-
# ensure last character is alphanumeric or '>' or '/'
|
308
|
-
until ele.match(/([[:alnum:]]|>|\/)$/) do
|
309
|
-
ele.chop!
|
310
|
-
end
|
311
|
-
ele
|
312
|
-
end
|
313
|
-
end.compact
|
230
|
+
url_strs = l_array.collect{|ele| ele.strip.include?('http') ? ele.strip : nil}.compact
|
314
231
|
debug('url_strs: ' << url_strs.to_s)
|
315
232
|
url_strs.each do |str|
|
316
233
|
# keep str for final replacement
|
@@ -318,13 +235,13 @@ class Body
|
|
318
235
|
debug( 'try to match http-link')
|
319
236
|
begin
|
320
237
|
# missing slashes ?
|
321
|
-
match = str.match(/(https?):(
|
238
|
+
match = str.match(/(https?):(\/{2})/)
|
322
239
|
if (!match || match.length != 3 || match[2] != '//')
|
323
|
-
debug 'cannot find
|
240
|
+
debug 'cannot find slashes in the URL'
|
324
241
|
if str.match(/https:/)
|
325
|
-
nstr = str.sub(/https
|
242
|
+
nstr = str.sub(/https:/, "https://")
|
326
243
|
elsif str.match(/http:/)
|
327
|
-
nstr = str.sub(/http
|
244
|
+
nstr = str.sub(/http:/, "http://")
|
328
245
|
end
|
329
246
|
debug ' with slashes: ' << nstr
|
330
247
|
end
|
@@ -335,9 +252,8 @@ class Body
|
|
335
252
|
match = nstr.match(/\<?(https?:\/\/[^\>]*)\>?/)
|
336
253
|
# get the darned URL already!
|
337
254
|
url = match[1] if match
|
338
|
-
|
339
|
-
|
340
|
-
l.sub!(str, nstr)
|
255
|
+
# nstr = with_angular_brackets(nstr, url)
|
256
|
+
return l.sub(str, nstr)
|
341
257
|
rescue Exception => ex
|
342
258
|
# this had looked intelligent, once.
|
343
259
|
line = __LINE__
|
@@ -348,17 +264,7 @@ class Body
|
|
348
264
|
exit false
|
349
265
|
end
|
350
266
|
end
|
351
|
-
|
352
|
-
return l
|
353
267
|
end
|
354
268
|
end
|
355
|
-
# ------- TEST --------
|
356
|
-
|
357
|
-
puts "eins zwei drei vier fünf sechs sieben acht neun zehn\n
|
358
|
-
eins zwei drei vier fünf sechs sieben acht neun zehn\n
|
359
|
-
\n
|
360
|
-
eins zwei drei vier fünf sechs sieben acht neun zehn\n
|
361
|
-
eins zwei drei vier fünf sechs sieben acht neun zehn".wrap!(20)
|
362
|
-
|
363
269
|
# Ω
|
364
270
|
|
data/lib/configuration.rb
CHANGED
@@ -25,6 +25,7 @@ class Configuration
|
|
25
25
|
include Singleton
|
26
26
|
include BasicLogging
|
27
27
|
|
28
|
+
self.extend(BasicLogging)
|
28
29
|
|
29
30
|
def initialize()
|
30
31
|
debug 'Configuration::initialize()'
|
@@ -91,15 +92,14 @@ class Configuration
|
|
91
92
|
end
|
92
93
|
@conf[:CONFIG_VERSION] = PROGVERSION.to_f
|
93
94
|
bak_conf = @config_file.dup << '_' << conf_version.to_s
|
94
|
-
bak_conf.gsub!('.' << PROGNAME, 'bak_' << PROGNAME)
|
95
95
|
info('Old configuration is saved to ' << bak_conf )
|
96
96
|
info('New configuration is saved to ' << @config_file )
|
97
97
|
begin
|
98
98
|
File::write(bak_conf, File.read(@config_file))
|
99
99
|
File::write(@config_file, @conf.to_yaml)
|
100
100
|
rescue Exception => ex
|
101
|
-
msg =
|
102
|
-
|
101
|
+
msg = ex.message
|
102
|
+
error "Cannot write altered configuration to " << @config_file << "!"
|
103
103
|
error msg
|
104
104
|
exit false
|
105
105
|
end
|
@@ -115,26 +115,19 @@ class Configuration
|
|
115
115
|
if File::exist?(@config_file) && File::readable?(@config_file)
|
116
116
|
begin
|
117
117
|
@conf = YAML::load_file(@config_file)
|
118
|
-
|
119
118
|
@conf.transform_keys!{|k| k.to_sym}
|
120
119
|
@keys = @conf.keys
|
121
120
|
clevel = @conf[:LOG_LEVEL]
|
122
121
|
set_level clevel
|
123
|
-
|
124
|
-
|
125
|
-
# clear the log file.
|
126
|
-
clear_log
|
127
|
-
debug('log target and -level set: ' << @@log_level.to_s << ', ' << target_string)
|
122
|
+
set_target @conf[:DEBUG_LOG]
|
123
|
+
debug('log target and -level set: ' << @@log_level.to_s << ', ' << @@target.path)
|
128
124
|
rescue Exception => ex
|
129
|
-
msg =
|
130
|
-
msg
|
131
|
-
# No log.
|
132
|
-
# error msg
|
133
|
-
STDERR.puts(msg << "\nAborting, bye\n")
|
125
|
+
msg = ex.message
|
126
|
+
error msg
|
134
127
|
exit false
|
135
128
|
end
|
136
129
|
else
|
137
|
-
STDERR.puts("
|
130
|
+
STDERR.puts("cannot read the configuration-file (" << @config_file << ")")
|
138
131
|
exit false
|
139
132
|
end
|
140
133
|
end
|