flnews_post_proc 1.7

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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 2c864ce301d84082376b2d6662eab044a8b9386d7fc59bea42ffa457811687d7
4
+ data.tar.gz: deb232cd41c1d3e8c96052eace342f022d440039beeb5b644e0697ecc3209888
5
+ SHA512:
6
+ metadata.gz: 523e37695eaef8c553b9458d7eba015e54ac709370368de54377f6b91c6a837a225f2f885e2c88b28aaf887ac33d4344f6d2b5b600e17f45e847c32327941ec9
7
+ data.tar.gz: 8c2c7747e1209268bedca5468c4cbc19251bab962c0783990444e0739042b7bf22444d714b466e656825ba0d8b76642d5eebf985a31c407049fc6a6c0d31e7e3
data/README.md ADDED
@@ -0,0 +1,381 @@
1
+ flnews_post_proc
2
+ =======================
3
+ Post-Processor for the flnews newsreader
4
+ ------------------------------------------
5
+
6
+ **IMPORTANT**
7
+ Please give priority to the documentation which is delivered with the gem
8
+ file, as the markdown syntax plays tricks, sometimes, and I may not be
9
+ quick enough to correct this file. This applies especially to the section
10
+ [_Configuration_](#CONFIGURATION), below.
11
+
12
+ The gem-file contains different formats of the man-page in English and French.
13
+ See section [_Source Code_](Source-Code), below, for instructions to access
14
+ these texts. Or see the same files [on the
15
+ Web](https://www.uplawski.eu/div/flnews/).
16
+
17
+ SYNOPSIS
18
+ =======================
19
+
20
+ An article is piped-in to the post-processor. This is normally done
21
+ automatically as soon as the variable “post_proc“ in the flnews configuration
22
+ file is set to the flnews_post_proc executable, i.e.:
23
+
24
+ **post_proc : /usr/local/bin/flnews_post_proc**
25
+
26
+ Locally stored articles can be piped in to the post-processor, as needed
27
+ for testing purposes, with a command-line like the following:
28
+
29
+ **flnews_post_proc < article**
30
+
31
+ INSTALLATION
32
+ =============
33
+ You must have a Ruby interpreter installed (see [ruby-lang.org](https://www.ruby-lang.org) ).
34
+ Your Linux distribution will probably let you choose one from its
35
+ software resources. Use the package management utility of your choice.
36
+
37
+ While you can download the current gem file for flnews_post_proc from
38
+ *[rubygems.org](https://www.rubygems.org)*, it is probably best to use the “gem”-utility
39
+ for the installation. It should be available from the same source as your
40
+ Ruby interpreter.
41
+
42
+ With the interpreter and the gem utility in place, the installation effort is
43
+ reduced to a simple command:
44
+ user@machine:~$ **sudo gem install flnews_post_proc**
45
+
46
+ This way, the gem file will be downloaded from rubygems.org and installed in
47
+ the designated path for ruby-gems. If the installation completes without
48
+ errors, the command **flnews_post_proc** will become immediately available.
49
+
50
+ For other uses of the gem utility, see the output of
51
+ user@machine:~$ **gem --help**
52
+
53
+ DESCRIPTION
54
+ =======================
55
+ The flnews newsreader is sufficient for Usenet access, i.e. to receive and read
56
+ articles from -, as well as to write and post articles to newsgroups.
57
+
58
+ When you compare news-clients, you will always notice the differences and
59
+ choose the software that you prefer. flnews however, has the charm that you can
60
+ influence how the program itself works but also modify posts that flnews
61
+ produces, just before the program will transmit them to the chosen nntp-server.
62
+
63
+ The flnews_post_proc can add and change details of a post, in ways that are
64
+ currently not possible with flnews alone. As the program is configurable, it
65
+ can probably respond to the needs of some Usenet users. You should, however,
66
+ rather take it as an example for what can be done and an inspiration for your
67
+ own creations.
68
+
69
+ The limits of a basic newsreader — what the program can do
70
+ ----------------------------------------------------------
71
+ While the articles that flnews creates, are complete and ready to be posted,
72
+ some users may not always agree with the result and for arbitrary reasons:
73
+
74
+ * There may be inconveniences when you post to different newsgroups in
75
+ different languages, as an introductory line which refers to a previous
76
+ post can only be set once in the flnews configuration. The consequence
77
+ can be that your post to a french newsgroup begins with an introduction
78
+ in English.
79
+ The post-processor program can set an introductory line specifically
80
+ chosen for one or several newsgroups.
81
+
82
+ * The same conflict arises, when you have set a standard signature text and
83
+ would like to replace it against another, based on the newsgroup you are
84
+ about to post to.
85
+ The post-processor program sets specific signatures as configured for one
86
+ or several newsgroups. You can even define a list of signatures and have
87
+ the program pick one from the list.
88
+
89
+ * Some custom headers may serve to convey additional information to
90
+ interested readers of your post, like GnuPG key IDs, your language skills
91
+ or the like. The signature may be a better choice than custom headers.
92
+ You are free. I just mention face and x-face but prefer that you do not
93
+ remember I did.
94
+ Custom headers may be defined in the configuration file for the program
95
+ and will then be added to each outgoing post.
96
+
97
+ * The Archive- and X-No-Archive headers are sometimes set to avoid that an
98
+ article be saved and stays available to search-engines (Google, notably).
99
+ Test- postings, for example, do probably not justify at all that they would
100
+ be referenced in search results. The post-processor program can impose the
101
+ Archive- and X-No-Archive header for all posts to certain newsgroups.
102
+
103
+ **ATTN** As of 2024, the header “X-No-Archive“ has lost most of its utility
104
+ and it is the decision of server operators to honor it or not.
105
+
106
+ * If a news post contains many references to either other posts or Web
107
+ pages, the text can be cluttered with URLs.
108
+ The post-processor can identify marked text fragments and transform them
109
+ into footnotes, which will be attached as a list at the bottom of the
110
+ post.
111
+ This works almost like the references-link in Wikipedia, but the delimiter
112
+ can be determined in the configuration file.
113
+ Example (with %=):
114
+ _This is an object %=and this becomes the footnote, describing the object
115
+ further=%_
116
+
117
+ * The program can attempt to correct ill formatted references. This is an
118
+ option, you can disable it by setting the option VFY_URLS to “no” in the
119
+ configuration. Only URLs starting with http or https are currently
120
+ handled.
121
+
122
+ Dialog to override settings
123
+ ---------------------------
124
+ You can have a dialog displayed just before the post-processor is invoked, to
125
+ **disable** some configuration options. Provided that either YAD, Zenity,
126
+ Whiptail or only xterm are available on your computer, you can choose from
127
+ the following options. You **cannot** use the dialog to enable options which
128
+ have not yet been set in the configuration.
129
+
130
+ * Signatures, as set in the configuration **can be ignored**. Either
131
+ a default signature will appear as set in flnews or none.
132
+ * Custom Headers, if configured, can be **omitted**.
133
+ * Archive- and X-No-Archive headers, if set for the current newsgroup, **can be
134
+ ignored**.
135
+ * The verification & correction of references **can be disabled**.
136
+ * Logging can be **switched off**, if set.
137
+
138
+ Pushing Esc or the cancle-button of the dialog interrupts the process, flnews
139
+ will not post the article.
140
+
141
+ You can disable the dialog, which ensures that all configured options will be
142
+ applied, without the need for further interaction (see below, option
143
+ OVERRIDE_CONFIG).
144
+
145
+ CONFIGURATION
146
+ ===============
147
+ On first execution of the program, a copy of the original configuration file is
148
+ created in */home/[user]/.flnews_post_proc.conf*
149
+ It is this file which is used from then on. If you delete it, it will be
150
+ recreated, on the next occasion, but your own changes will be lost.
151
+
152
+ The configuration file is in YAML syntax and full of explanations. The
153
+ variables defined in this file can be classified as belonging to one of two
154
+ categories:
155
+
156
+ * Variables describing values originally set by flnews, which should be used or
157
+ replaced. The important elements are usually matched in a capture group.
158
+
159
+ * Variables defining the new or altered content.
160
+
161
+ *ATTENTION*: Most problems that occurred with recent versions of
162
+ *flnews_post_proc* were caused by inadequate option values and very often ill
163
+ chosen or mal formatted regular expressions. PSE double check your
164
+ configuration, if the program does not seem to work normally.
165
+
166
+ **FUP_NAME**
167
+ A Regular Expression, describing the string which contains the name of
168
+ previous poster who is the author of a quoted post. This string is
169
+ recognized in the original article and may be used with the fitting element
170
+ rom *GROUP_INTRO*, below. The Regexp format is that of the Regexp class in
171
+ Ruby, noted as a String. Beware to mask a backslash '\\' by another one,
172
+ ike in the example. A capture-group '()' serves to extract the name from the
173
+ match result.
174
+
175
+ Leave this field empty to keep the default from the flnews configuration
176
+ intact.
177
+
178
+ CONTENT: A String equivalent of a regular expression.
179
+
180
+ DEFAULT: EMPTY
181
+
182
+ EXAMPLE1: _"On \\d+.\\d+.\\d{2,4} at \\d+:\\d+ **(.*)** wrote:"_
183
+
184
+ EXAMPLE2: _"**(.*)** wrote:"_
185
+
186
+ **FUP_GROUP**
187
+ A Regular Expression, describing the string which contains the newsgroup
188
+ where the previous post, that you are referring to in the followup, had been
189
+ published.
190
+
191
+ Leave this field empty to ignore the precise group.
192
+
193
+ CONTENT: A String equivalent of a regular expression.
194
+
195
+ DEFAULT: EMPTY
196
+
197
+ EXAMPLE: "wrote in **(.*)**:"
198
+
199
+ **GROUP_INTROS**
200
+ Introductory strings, referring to the previous poster who is the author of a
201
+ quoted post. If you match the newsgroup of the post (see FUP_GROUP), you can
202
+ use these variables in the result.
203
+ Currently only %fup_name% and %fup_group% are reproduced in the resulting
204
+ introductory string.
205
+
206
+ CONTENT: A newsgroup or regexp per line, followed by a colon, a space and a String
207
+
208
+ DEFAULT: As configured in flnews
209
+
210
+ EXAMPLE: _alt.test: "Thus spoke #\{fup_name\} on that baleful #\{fup_date\}:"_
211
+
212
+ **GROUP_SIGS**
213
+ A signature line per Newsgroup.
214
+ If a file is named instead, the program will pick randomly one signature from
215
+ that file. The file should contain signatures, separated by 1 empty line.
216
+
217
+ ATTN! In multi line signatures, you have to use \r\n for line breaks.
218
+
219
+ CONTENT: A newsgroup or regexp per line, followed by a colon, a space and a String.
220
+
221
+ DEFAULT: As configured in flnews
222
+
223
+ EXAMPLE: alt.test: _"Signature for alt.test\\\\r\\\\nsecond line"_
224
+ EXAMPLE: comp.*: /home/user/.my_sigs
225
+
226
+ **CUSTOM_HEADERS**
227
+ Additional headers for the outgoing article
228
+
229
+ CONTENT: 1 line per header : a dash and space, then a String, comprising the
230
+ name of the header, ending in a colon and the value of the header.
231
+
232
+ DEFAULT: undefined
233
+
234
+ EXAMPLE (2 headers):
235
+ _\- 'X-My-Header: nothing fancy'_
236
+ _\- 'X-Another-Header: care not!'_
237
+
238
+ **NO_ARCHIVE_GROUPS**
239
+
240
+ The newsgroups, where the headers “Archive: no” and “X-No-Archive: YES” shall
241
+ be set.
242
+
243
+ CONTENT: a dash and space, then a String, containing the name of the group or
244
+ a regexp.
245
+
246
+ DEFAULT: empty
247
+
248
+ EXAMPLE (1 group, 1 hierarchy):
249
+ _\- "alt.test"_
250
+ _\- "^news.*"_
251
+
252
+
253
+ **DEBUG_LOG**
254
+ The name of a file, where debug messages are written. Setting this
255
+ variable will enable the log. Leave empty to disable logging.
256
+
257
+ CONTENT: The name of a writable file, which will be created if inexistent
258
+ and overwritten if need be.
259
+
260
+ DEFAULT: empty
261
+
262
+ EXAMPLE: _'/tmp/a_log-file.txt'_
263
+
264
+ **LOG LEVEL**
265
+ One of debug, fatal, error, info, warn
266
+
267
+ **REFERENCES_SEPARATOR**
268
+ A sequence of 2 or more symbols marking the end of the message-body and the
269
+ beginning of a list of “references” or “footnotes”. It will only appear, if
270
+ the original message-body contains text marked for use as such a footnote. See
271
+ *REFERENCES_DELIMITER*.
272
+
273
+ If the option is not defined or empty, the list of footnotes will appear
274
+ below the last line of the message body and no separator will be inserted.
275
+
276
+ CONTENT: A quoted symbol or sequence of symbols.
277
+
278
+ DEFAULT: empty
279
+
280
+ EXAMPLE: _'---------'_
281
+
282
+ **REFERENCES_DELIMITER**
283
+ A symbol or sequence of symbols marking the beginning of a text which will
284
+ serve as footnote (or reference). The **reversed sequence** musst be used to
285
+ mark the end of the text. The presence of this sequence or symbol in the
286
+ original message body will cause the enclosed text to be moved below the
287
+ message body.
288
+ The *REFERENCES_SEPARATOR*, if defined, will separate the message from the
289
+ list of footnotes.
290
+
291
+ If this option is not defined or empty, footnotes are not created.
292
+
293
+ CONTENT a quoted symbol or sequence of symbols.
294
+
295
+ DEFAULT: none/empty
296
+
297
+ EXAMPLE: _'%?'_
298
+
299
+ **REFERENCE_FORMAT**
300
+ A format-string, using %s for a number, replacing the reference text in the
301
+ message body.
302
+
303
+ DEFAULT: " %s)" -> becomes 1) ... 2) ... 3)
304
+
305
+ EXAMPLE: _"(%s)" -> becomes (1) ... (2) ... (3)_
306
+
307
+ **VFY_URLS**
308
+ A Boolean constant. It determines if the program shall verify and possibly
309
+ try to correct URLs. Even if URLs are identified as such, only a few
310
+ manipulations are attempted :
311
+
312
+ * Angular brackets '<' and '>' are added, if missing
313
+ * Slashes are added, if they are found missing after "http(s):"
314
+
315
+ If the variable is not set, a value 'yes' is assumed.
316
+
317
+ CONTENT: One of YES, yes, NO, no, and other variations of case.
318
+
319
+ DEFAULT: yes
320
+
321
+ EXAMPLE: ... I let you guess.
322
+
323
+ **OVERRIDE_CONFIG**
324
+ GROUP_SIGS, XNAY_GROUPS, CUSTOM_HEADERS and DEBUG_LOG.
325
+ A dialog may be displayed which allows you to disable any of these
326
+ four options, so that the defaults from flnews prevail.
327
+
328
+ ATTN! Canceling the dialog or pushing the Esc-key does interrupt
329
+ the process. flnews will not post the article.
330
+
331
+ Set this option to no, NO or similar to disable the dialog.
332
+
333
+ DEFAULT: yes
334
+
335
+ EXAMPLE: No
336
+
337
+ Other Information
338
+ =================
339
+
340
+ Testing
341
+ -------
342
+ The effects that the execution of the program will have on a posting can be
343
+ verified in two ways:
344
+
345
+ 1. By piping-in a post that had previously been saved to a file:
346
+ **:~$ /usr/local/bin/[post-processor] < [test-article]**
347
+ This will show the resulting new version of the article on screen, but you
348
+ can also pipe the output into another file. This is a great way to test a
349
+ program during development or to test your own configuration of the program.
350
+
351
+ 2. By posting directly into a test-newsgroup (like alt.test or similar). This
352
+ is mandatory before you really post to thematic newsgroups and when the
353
+ settings of the post-processor will affect the article.
354
+
355
+
356
+ Source-Code
357
+ -----------
358
+ The gem-file that you get with the gem-utility or from rubygems.org contains
359
+ all the code of the program and some documentation (this page notably). To read
360
+ its content, you must
361
+
362
+ 1. untar the gem-file with tar _-xf flnews_post_proc-0.1.gem_
363
+ 2. uncompress the data.gz archive: _gunzip data.gz_
364
+ 3. untar the resultig data.tar archive: _tar -xf data.tar_
365
+
366
+ This creates the directories bin, doc and lib.
367
+
368
+ License
369
+ -------
370
+ flnews_post_proc is distributed under the conditions of the WTFPL-2.0 or later
371
+ License (see http://www.wtfpl.net/txt/copying/ or license-text in the doc
372
+ directory of the gem-file).
373
+
374
+ Author
375
+ -----
376
+ flnews_post_proc has been developed by
377
+ Michael Uplawski <michael.uplawski@uplawski.eu>
378
+
379
+ Ω
380
+ ==
381
+
@@ -0,0 +1,128 @@
1
+ #!/bin/env ruby
2
+ #encoding: UTF-8
3
+
4
+ =begin
5
+ /***************************************************************************
6
+ * ©2023-2024, Michael Uplawski <michael.uplawski@uplawski.eu> *
7
+ * *
8
+ * This program is free software; you can redistribute it and/or modify *
9
+ * it under the terms of the DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE *
10
+ * *
11
+ * This program is distributed in the hope that it will be useful, *
12
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
13
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
14
+ * *
15
+ ***************************************************************************/
16
+ =end
17
+ # This program is Linux only
18
+ if ! /linux/ =~ RUBY_PLATFORM
19
+ msg = "ERROR ! This script #{$0} cannot be used with #{RUBY_PLATFORM}"
20
+ msg << "\n\tABORTING! Bye."
21
+ STDERR.puts msg
22
+ exit false
23
+ end
24
+
25
+ # needs the ruby-filemagic gem
26
+ # require 'filemagic'
27
+ # require 'marcel'
28
+ require 'tempfile'
29
+
30
+ require_relative '../lib/override'
31
+ require_relative '../lib/flnews_post_proc'
32
+ require_relative '../lib/basic_logging'
33
+ require_relative '../lib/configuration'
34
+ require_relative '../lib/version'
35
+
36
+ self.extend(BasicLogging)
37
+
38
+ def usage
39
+ usage = "\nWhat do you want me to do? Where is the article to post-process?"
40
+ usage << "\nUsage: "
41
+ usage << "\n\t#{$0} < article.text"
42
+ info usage
43
+ STDERR.puts usage
44
+ exit false
45
+ end
46
+
47
+ msg = PROGNAME.dup << ' ' << PROGVERSION << ' starting'
48
+ msg = "–––––– " << msg << " ––––––"
49
+ info msg
50
+ # Get a configuration
51
+ # this call results in the configuration file to be
52
+ # read and interpreted. As the log depends on the
53
+ # configuration, errors may render the debug-log
54
+ # unavailable. See STDERR in these cases, i.e.
55
+ # call the program on the command-line and pipe-in
56
+ # a message. Is this okay?
57
+ debug 'creating config'
58
+ config = Configuration::instance
59
+
60
+ # Store the path to the main executable
61
+ # ... Forgot what this should be good for.
62
+ # config.set(:BINDIR, File::dirname(__FILE__) )
63
+
64
+ # Only if data is on STDIN
65
+ if (!STDIN.tty?)
66
+ # read from STDIN
67
+ artext = ARGF.read
68
+
69
+ # There is content, create the post-processor.
70
+ if !artext.strip.empty?
71
+ =begin
72
+ # unused
73
+ if (['news', 'rfc822'].none? {|m| mime.start_with?('message/' << m) } )
74
+ # Not a pure news message
75
+ # Add more reactions, as you stumble upon them ...
76
+ warn ("Input is of wrong mime-type " << mime.split(';')[0])
77
+
78
+ # Javascript okay
79
+ if (['javascript'].any? {|m| mime.start_with?('application/' << m)} )
80
+ warn 'Input contains java-script code!'
81
+ # C okay
82
+ elsif(['x-c'].any? {|m| mime.start_with?('text/' << m)} )
83
+ warn 'Input contains C- or C++ code!'
84
+ # Ruby okay
85
+ elsif(['x-ruby'].any? {|m| mime.start_with?('text/' << m) })
86
+ warn 'Input contains Ruby-code!'
87
+ else
88
+ warn 'Input contains other things than plain-text, but I cannot say, what.'
89
+ end
90
+ end
91
+ =end
92
+ #----------->
93
+ # Allow to override the configuration,
94
+ # if not disabled (default is true)
95
+ if config.OVERRIDE_CONFIG != false
96
+ cdlg = OverrideDlg.new
97
+ discarded = cdlg.show
98
+ if discarded && !discarded.empty?
99
+ debug('options overriden ' << discarded)
100
+ OverrideDlg.cvars.each do |v|
101
+ if discarded.include?(v.to_s)
102
+ debug('removing ' << v.to_s)
103
+ config.set(v, nil)
104
+ end
105
+ end
106
+ end
107
+ debug('new config: ' << config.inspect)
108
+ end
109
+ #<--------------
110
+ # Do it:
111
+ pp = PostProcessor.new(artext)
112
+ # and get a result.
113
+ article = pp.article
114
+ if article
115
+ # -------------> The main objective <------
116
+ puts article
117
+ # <------------- over and out ------>
118
+ exit true
119
+ end
120
+ # whatever.
121
+ exit false
122
+ else
123
+ error( "Cannot read the article, no content" )
124
+ end
125
+ else
126
+ usage()
127
+ end
128
+ # Ω