flnews_post_proc 1.40
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +374 -0
- data/bin/flnews_post_proc +84 -0
- data/doc/html/flnews_post_proc.html +654 -0
- data/doc/html/flnews_post_proc_fr.html +701 -0
- data/doc/license.txt +13 -0
- 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 +334 -0
- data/doc/rst/flnews_post_proc_fr.rst +377 -0
- data/lib/basic_logging.rb +170 -0
- data/lib/body.rb +270 -0
- data/lib/color_output.rb +65 -0
- data/lib/configuration.rb +136 -0
- data/lib/flnews_post_proc.conf +172 -0
- data/lib/flnews_post_proc.rb +71 -0
- data/lib/headers.rb +148 -0
- data/lib/newsgroups.rb +134 -0
- data/lib/override.rb +199 -0
- data/lib/ruby_dlg +136 -0
- data/lib/version.rb +21 -0
- data/lib/whiptail_dlg +79 -0
- data/lib/yad_dlg +52 -0
- data/lib/zenity_dlg +59 -0
- metadata +88 -0
@@ -0,0 +1,377 @@
|
|
1
|
+
=======================
|
2
|
+
flnews_post_proc
|
3
|
+
=======================
|
4
|
+
------------------------------------------
|
5
|
+
Post-Traitement pour flnews
|
6
|
+
------------------------------------------
|
7
|
+
|
8
|
+
SYNOPSIS
|
9
|
+
=======================
|
10
|
+
|
11
|
+
Un article est envoyé au logiciel de post-traitement via STDIN. Ceci se passe
|
12
|
+
automatiquement, quand la variable « post_proc » dans le fichier de
|
13
|
+
configuration de flnews a la valeur *flnews_post_proc*.
|
14
|
+
|
15
|
+
Si un article a été sauvegardé dans un fichier, il peut servir pour tester le
|
16
|
+
fonctionnement de flnews_post_proc, en lançant une commande comme :
|
17
|
+
|
18
|
+
**flnews_post_proc < article.txt**
|
19
|
+
|
20
|
+
ou si vous préférez l'équivalent :
|
21
|
+
|
22
|
+
**cat article.txt | flnews_post_proc**
|
23
|
+
|
24
|
+
DESCRIPTION
|
25
|
+
=======================
|
26
|
+
|
27
|
+
Le lecteur de news **flnews** est suffisant pour l'accès au Usenet, c'est à
|
28
|
+
dire pour lire les articles et pour les rédiger et les envoyer aux newsgroups
|
29
|
+
de votre choix.
|
30
|
+
|
31
|
+
Quand vous comparez les clients pour les news, vous allez toujours identifier
|
32
|
+
le logiciel qui correspond à vos attentes et vos habitudes. Flnews, comme un
|
33
|
+
logiciel basique, vous offre la possibilité d'influencer comment il fonctionne
|
34
|
+
et aussi de manipuler directement les articles qu'il produit, juste avant qu'ils
|
35
|
+
soient envoyés au serveur nntp.
|
36
|
+
|
37
|
+
Ce post-traitement peut servir à ajouter et à modifier des détails du message
|
38
|
+
d'une manière qui n'est actuellement pas possible avec seulement flnews. Comme
|
39
|
+
le logiciel est configurable, il peut probablement répondre aux besoins de
|
40
|
+
quelques utilisateurs du Usenet. Quand même, vous devez le comprendre comme un
|
41
|
+
exemple pour ce qui est possible et pour inspiration, afin de créer vos propres
|
42
|
+
solutions.
|
43
|
+
|
44
|
+
Les limites d'un lecteur basique de news – ce qui peut faire flnews_post_proc
|
45
|
+
-----------------------------------------------------------------------------
|
46
|
+
|
47
|
+
Bien que les articles qui sont créés avec flnews sont complets et prêt pour
|
48
|
+
l'envoi, certains utilisateurs ne seront pas toujours d'accord avec le résultat
|
49
|
+
et ce pour des raisons arbitraires :
|
50
|
+
|
51
|
+
* Il peut y avoir des inconvénients quand vous communiquez dans de groupes
|
52
|
+
diverses en plusieurs langues. La ligne d'introduction qui fait référence à
|
53
|
+
un article précédent, ne peut être configurée qu'une seule fois pour flnews.
|
54
|
+
La conséquence peut être une introduction en Anglais quand vous postez dans
|
55
|
+
un groupe français.
|
56
|
+
|
57
|
+
Avec mon logiciel de post-traitement vous pouvez imposer des introductions
|
58
|
+
spécifiques, à chaque fois pour une ou plusieurs newsgroups.
|
59
|
+
|
60
|
+
* Le même conflit se produit quand vous avez défini une signature mais voudriez
|
61
|
+
la remplacer contre une autre, selon le groupe dans lequel vous êtes en train
|
62
|
+
de poster.
|
63
|
+
|
64
|
+
flnews_post_proc peut faire exactement ça, quand vous avez configuré quel
|
65
|
+
signature doit apparaître dans quel newsgroup ou liste de newsgroups.
|
66
|
+
|
67
|
+
* Quelques entêtes supplémentaires peuvent servir à transmettre des informations
|
68
|
+
aux lecteurs intéressés, comme l'ID de votre clé GnuPG, vos connaissances en
|
69
|
+
langues ou pareil. Il se trouve que la signature est mieux pour ça, mais vous
|
70
|
+
êtes libres. Je veux mentionner « face » et « x-face » mais préfère que vous
|
71
|
+
ne vous en souvenez pas.
|
72
|
+
|
73
|
+
Ces entêtes, – Custom-Headers – peuvent être définis dans la configuration
|
74
|
+
du logiciel et vont être utilisées dans chaque article sortant.
|
75
|
+
|
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
|
+
|
82
|
+
Avec flnews_post_proc vous pouvez décider et imposer que vos articles dans
|
83
|
+
certains newsgroups contiendront d'office une entête **X-No-Archive: Yes**.
|
84
|
+
|
85
|
+
**ATTN** Depuis l'année 2024, cet entête n'a probablement plus de fonction.
|
86
|
+
|
87
|
+
* Certains messages mentionnent d'autres articles ou des URLs de pages Web.
|
88
|
+
S'ils sont nombreux, ces références peuvent déranger la lecture à cause de
|
89
|
+
leur syntaxe spécifique.
|
90
|
+
|
91
|
+
Mon logiciel est capable d'identifier des fragments de text marqué – pas
|
92
|
+
seulement des références – et les transformer en notes en bas de page. Vous
|
93
|
+
pouvez imaginer ça comme le fonctionnement de la balise <ref/> de Wikipedia,
|
94
|
+
mais vous pouvez définir votre propre séparateur pour marquer les fragments
|
95
|
+
de text dans le fichier de configuration.
|
96
|
+
|
97
|
+
Exemple ( avec séparateur **%=** ) :
|
98
|
+
« Ceci est un objet %=et ceci devient la note en bas de page, qui décrit
|
99
|
+
l'objet plus précisement=% »
|
100
|
+
|
101
|
+
Dialogue pour désactiver des options
|
102
|
+
------------------------------------
|
103
|
+
Juste avant d'entrer en action, flnews_post_proc peut afficher un dialogue, qui
|
104
|
+
vous laisse **désactiver** des options fixées dans la configuration. Sous
|
105
|
+
condition qu'un des outils YAD, Zenity, Whiptail ou seulement xterm est
|
106
|
+
disponible, vous pouvez choisir dans les options suivantes, ceux que vous
|
107
|
+
voulez ignorer pour l'article en préparation. Vous **ne pouvez pas** activer
|
108
|
+
des options, qui ne l'ont pas été auparavant :
|
109
|
+
|
110
|
+
* Signatures, comme définis dans la configuration **peuvent être ignorées**.
|
111
|
+
Soit une signature par défaut sera appliquée, si prévue, ou aucune.
|
112
|
+
|
113
|
+
* Entêtes supplémentaires, si définis, peuvent rester absentes de l'article.
|
114
|
+
|
115
|
+
* L'entête X-No-Archive, si prévu pour le newsgroup choisi, peut être ignoré.
|
116
|
+
|
117
|
+
* L'auto correction de URLs et références à d'autres articles peut être
|
118
|
+
désactivé.
|
119
|
+
|
120
|
+
* L'écriture d'un protocole peut être arrêtée.
|
121
|
+
|
122
|
+
En tapant Esc ou en poussant le bouton « Annuler » du dialogue, vous pouvez
|
123
|
+
interrompre le processus, flnews ne vas pas envoyer l'article.
|
124
|
+
|
125
|
+
Vous pouvez même désactiver le dialogue, ce qui assure que toutes les options
|
126
|
+
configurées seront appliquées sans plus d'interaction ( à voir dessous : optoin
|
127
|
+
OVERRIDE_CONFIG ).
|
128
|
+
|
129
|
+
CONFIGURATION
|
130
|
+
=============
|
131
|
+
La première fois que vous exécutez le logiciel, une copie de la configuration
|
132
|
+
par défaut sera écrit dans */home/[utilisateur]/.flnews_post_proc.conf* C'est
|
133
|
+
ce fichier qui sera désormais utilisé. Si vous l'effacez, il sera recréé à la
|
134
|
+
prochaine occasion, mais vos modifications seront perdues.
|
135
|
+
|
136
|
+
Le fichier de configuration est en format YAML et plein d'explications. Les
|
137
|
+
variables définis dans ce fichier peuvent être classées en deux catégories :
|
138
|
+
|
139
|
+
* Variables qui décrivent des valeurs déterminées par flnews. Ils peuvent être
|
140
|
+
utiilisées ou remplacées. Les composants importants sont normalement
|
141
|
+
spécifiés dans une « capture group ».
|
142
|
+
|
143
|
+
* Variables qui définissent du nouveau contenu ou des changements dans le
|
144
|
+
contenu.
|
145
|
+
|
146
|
+
**FUP_NAME**
|
147
|
+
Une « expression régulière » ( “regular expression” ) décrivant la chaîne de
|
148
|
+
caractères qui contient le nom de l'auteur d'un article précédent, qu'on veut
|
149
|
+
citer en partie. Cet élément est reconnu dans l'article d'origine et peut
|
150
|
+
être utilisé à la place de l'élément correspondant dans *GROUP_INTRO* ( à voir
|
151
|
+
plus bas ). Le format de l'expression est celui de la classe Regexp dans Ruby.
|
152
|
+
Veillez de masquer le backslash '\\' avec un autre, comme dans l'exemple. Un
|
153
|
+
« capture group » '()' sert à extraire le nom du résultat de la comparaison.
|
154
|
+
|
155
|
+
Laissez ce champs vide afin de maintenir le comportement configuré pour flnews.
|
156
|
+
|
157
|
+
CONTENU : L'équivalent d'une regular expression en chaîne de caractères.
|
158
|
+
|
159
|
+
PAR DÉFAUT : Vide
|
160
|
+
|
161
|
+
EXEMPLE 1 : "On \\\\d+.\\\\d+.\\\\d{2,4} at \\\\d+:\\\\d+ **(.*)** wrote:"
|
162
|
+
|
163
|
+
EXEMPLE 2 : "**(.*)** wrote:"
|
164
|
+
|
165
|
+
**FUP_GROUP**
|
166
|
+
Une « expression régulière » ( “regular expression” ) décrivant la chaîne de
|
167
|
+
caractères qui contient le newsgroup où a été publié l'article précédent à qui nous
|
168
|
+
faisons référence dans un « followup ».
|
169
|
+
|
170
|
+
Laissez ce champs vide afin d'ignorer le groupe précis.
|
171
|
+
|
172
|
+
CONTENU : l'équivalent d'une regular expression en chaîne de caractères.
|
173
|
+
|
174
|
+
PAR DÉFAUT : Vide
|
175
|
+
|
176
|
+
EXEMPLE : "wrote in **(.*)**:"
|
177
|
+
|
178
|
+
**GROUP_INTROS**
|
179
|
+
Des introductions qui font référence à l'auteur de l'article précédent que
|
180
|
+
nous souhaitons citer. Si vous avez trouvé le newsgroup où l'article a été
|
181
|
+
publié ( à voir : FUP_GROUP, ci-dessus ), et le nom de son auteur
|
182
|
+
( FUP_NAME ), vous pouvez utiliser ces valeurs ici.
|
183
|
+
|
184
|
+
Jusqu'à prochaine ordre, seulement %fup_name% est %fup_group% sont reproduit
|
185
|
+
dans l'introduction resultant.
|
186
|
+
|
187
|
+
| CONTENU : Un newsgroup ou regexp par ligne, suivi de deux points, un espace et
|
188
|
+
| une chaîne de caractères.
|
189
|
+
|
190
|
+
PAR DÉFAUT : Comme configuré dans flnews.
|
191
|
+
|
192
|
+
| EXEMPLE ( un groupe et une hiérarchie ) :
|
193
|
+
| alt.test: "Thus spoke %fup_name% in %fup_group%"
|
194
|
+
| fr\\.*: "C'était dans %fup_group%, que %fup_name% c'est exprimé ainsi"
|
195
|
+
|
196
|
+
**GROUP_SIGS**
|
197
|
+
Une signature par newsgroup ou expression.
|
198
|
+
ATTN! Vous devez noter \\r\\n pour les sautes de lignes, si une signature
|
199
|
+
s'étend sur plusieurs lignes.
|
200
|
+
|
201
|
+
CONTENU : un newsgroup ou expression par ligne, suivi de deux poins, un espace
|
202
|
+
et une chaîne de caractères.
|
203
|
+
|
204
|
+
PAR DÉFAUT : Comme configuré dans flnews.
|
205
|
+
|
206
|
+
EXEMPLE : fr.test: "Signature pour alt.test\\r\\nseconde ligne"
|
207
|
+
|
208
|
+
**CUSTOM_HEADERS**
|
209
|
+
Entêtes supplémentaires pour l'article sortant.
|
210
|
+
|
211
|
+
CONTENU : 1 ligne par entête : un trait d'union, un espace, puis une chaîne de
|
212
|
+
caractères comprenant le nom de l'entête, puis deux points et la valeur de
|
213
|
+
l'entête.
|
214
|
+
|
215
|
+
PAR DÉFAUT : Vide ( pas défini )
|
216
|
+
|
217
|
+
| EXEMPLE ( 2 entêtes ) :
|
218
|
+
| - 'X-My-Header: nothing fancy'
|
219
|
+
| - 'X-Another-Header: care not!'
|
220
|
+
|
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.
|
224
|
+
|
225
|
+
CONTENU : Un trait d'union et un espace, puis une chaîne de caractères,
|
226
|
+
contenant le nom du groupe ou une expression.
|
227
|
+
|
228
|
+
PAR DÉFAUT : Vide
|
229
|
+
|
230
|
+
| EXEMPLE ( 1 groupe, 1 hiérarchie ) :
|
231
|
+
| - "alt.test"
|
232
|
+
| - "^news.*"
|
233
|
+
|
234
|
+
|
235
|
+
**DEBUG_LOG**
|
236
|
+
Le nom d'un fichier, qui va servir comme protocol. Si le nom d'un fichier
|
237
|
+
valide est donné, le protocol est activé. Laissez vide pour désactiver le
|
238
|
+
protocol.
|
239
|
+
|
240
|
+
| CONTENU : Le nom d'un fichier dont les droits permettent l'écriture.
|
241
|
+
| Il sera créé s'il n'existe pas encore et remplacé à chaque exécution
|
242
|
+
| du logiciel.
|
243
|
+
|
244
|
+
PAR DÉFAUT : Vide
|
245
|
+
|
246
|
+
EXEMPLE : '/tmp/a_log-file.txt'
|
247
|
+
|
248
|
+
**LOG LEVEL**
|
249
|
+
Un de debug, fatal, error, info, warn
|
250
|
+
|
251
|
+
| EXEMPLE :
|
252
|
+
| LOG_LEVEL: 'debug'
|
253
|
+
|
254
|
+
**REFERENCES_SEPARATOR**
|
255
|
+
Un symbole ou une séquence de symboles qui marquent la fin du corps du message
|
256
|
+
et le début d'une liste de « références » ou « notes de pied de page ». Il
|
257
|
+
apparaîtra seulement, si le message contient du text marqué pour servir comme
|
258
|
+
note de pied de page. À voir *REFERENCES_DELIMITER* ci-dessous.
|
259
|
+
|
260
|
+
Si l'option n'est pas défini ou vide, la liste suit à la dernière ligne du
|
261
|
+
corps du message, sans séparation supplémentaire.
|
262
|
+
|
263
|
+
CONTENU : Un symbol ou séquence de symboles entre guillemets " " ou ' '.
|
264
|
+
|
265
|
+
PAR DÉFAUT : Vide
|
266
|
+
|
267
|
+
EXEMPLE : '---------'
|
268
|
+
|
269
|
+
**REFERENCES_DELIMITER**
|
270
|
+
Une séquence d'au moins deux symboles qui marque le début d'un text qui sera
|
271
|
+
transformé en note de pied de page ( ou référence ). La **séquence inversée**
|
272
|
+
doit marquer la fin du même fragment de text. La présence de cette séquence
|
273
|
+
dans le message d'origine, a comme conséquence que le text marqué sera déplacé
|
274
|
+
vers la fin, au-dessous du corps du message.
|
275
|
+
Si *REFERENCES_SEPARATOR* ( option ci-dessus ) est défini, il va séparer le message
|
276
|
+
de la liste des notes du pied de page.
|
277
|
+
|
278
|
+
Laissez ce champs vide pour éviter la création des noted du pied de page.
|
279
|
+
|
280
|
+
CONTENU : Une séquence de symboles entre guillemets ( '' )
|
281
|
+
|
282
|
+
PAR DÉFAUT : Vide
|
283
|
+
|
284
|
+
EXEMPLE: '%?'
|
285
|
+
|
286
|
+
**REFERENCE_FORMAT**
|
287
|
+
Une chaîne de formatage, contenant %s pour représenter une nombre, qui
|
288
|
+
remplace le texte d'une future note du pied de page dans le corps du message.
|
289
|
+
|
290
|
+
PAR DÉFAUT : " %s)" -> devient 1) ... 2) ... 3)
|
291
|
+
|
292
|
+
EXEMPLE : "(%s)" -> devient (1) ... (2) ... (3)
|
293
|
+
|
294
|
+
**VFY_URLS**
|
295
|
+
Une constante booléen. Elle détermine si le programme doit essayer de corriger
|
296
|
+
des URIs. Même si les URIs sont identifiables, seulement quelques manipulations
|
297
|
+
sont temptées :
|
298
|
+
|
299
|
+
* '<' et '>' sont ajoutés, si manquants
|
300
|
+
* "news:" est ajouté au début des références à d'autres articles
|
301
|
+
* Des slashes sont insérés, s'ils manquent après "http(s):"
|
302
|
+
|
303
|
+
ATTN! Le programme ne peut pas différencier entre "mailto:" et "news:". Si ni l'un
|
304
|
+
ni l'autre est donné, mais '@' est présent, "news:" est ajouté automatiquement.
|
305
|
+
|
306
|
+
Si la variable n'est pas défini, la valeur 'yes' est présumée.
|
307
|
+
|
308
|
+
CONTENU: Un de YES, yes, NO, no, et autres tels variations
|
309
|
+
|
310
|
+
PAR DÉFAUT: yes
|
311
|
+
|
312
|
+
EXEMPLE: No
|
313
|
+
|
314
|
+
**OVERRIDE_CONFIG**
|
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.
|
320
|
+
|
321
|
+
ATTN ! En poussant Esc ou le bouton « Annuler » du dialogue, vous interrompez
|
322
|
+
le programme et flnews ne va rien envoyer.
|
323
|
+
|
324
|
+
Notez la valeur 'no', 'NO' ou pareil pour désactiver le dialogue.
|
325
|
+
|
326
|
+
PAR DÉFAUT : yes
|
327
|
+
|
328
|
+
EXEMPLE: No
|
329
|
+
|
330
|
+
Autres Informations
|
331
|
+
===================
|
332
|
+
|
333
|
+
Tester
|
334
|
+
------
|
335
|
+
L'effet qu'aura l'exécution du programme peut être vérifié de deux manières :
|
336
|
+
|
337
|
+
1. En fournissant un article, sauvegardé auparavant dans un fichier :
|
338
|
+
|
339
|
+
**:~$ /usr/local/bin/[post-processor] < [test-article]**
|
340
|
+
|
341
|
+
Ceci va vous présenter la nouvelle version de l'article sur l'écran, mais
|
342
|
+
vous pouvez aussi diriger le résultat dans un autre fichier. C'est une
|
343
|
+
excellente technique pour tester un logiciel pendant le développement ou
|
344
|
+
votre configuration avant que vous vous en servez.
|
345
|
+
|
346
|
+
2. En envoyant un message directement dans un groupe de test ( comme alt.test,
|
347
|
+
fr.test ou similaires ).
|
348
|
+
Ceci est obligatoire avant que vous postez dans des groupes thématiques et
|
349
|
+
si les réglages du post-traitement vont modifier l'article.
|
350
|
+
|
351
|
+
Code source
|
352
|
+
-----------
|
353
|
+
Le fichier flnews_post_proc.gem, que vous recevez à l'aide de l'outil *gem* ou
|
354
|
+
directement du site *rubygems.org*, contient tout le code source du logiciel et
|
355
|
+
de la documentation ( cette page notamment ). Pour lire le code du logiciel,
|
356
|
+
vous devez
|
357
|
+
|
358
|
+
1. utiliser *tar -xf flnews_post_proc-[version].gem*
|
359
|
+
2. décomprimer l'archive data.gz : *gunzip data.gz*
|
360
|
+
3. Extraire le contenu du fichier résultant « data.tar » :
|
361
|
+
*tar -xf data.tar*
|
362
|
+
|
363
|
+
À la fin les répertoires bin, doc et lib seront créés.
|
364
|
+
|
365
|
+
License
|
366
|
+
-------
|
367
|
+
flnews_post_proc est distribué sous les conditions de la WTFPL-2.0 ou plus
|
368
|
+
récent ( À voir http://www.wtfpl.net/txt/copying/ ou license-text dans le
|
369
|
+
répertoire « doc » de la gem ).
|
370
|
+
|
371
|
+
Auteur
|
372
|
+
------
|
373
|
+
| flnews_post_proc a été développé par
|
374
|
+
| Michael Uplawski <michael.uplawski@uplawski.eu>
|
375
|
+
|
376
|
+
Ω
|
377
|
+
==
|
@@ -0,0 +1,170 @@
|
|
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
|
+
#
|
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)
|
52
|
+
lv = Levels[lv.to_sym]
|
53
|
+
end
|
54
|
+
|
55
|
+
if(!lv || (lv.respond_to?(:to_int) && lv >= DEBUG && lv <= FATAL) )
|
56
|
+
@@log_level = lv
|
57
|
+
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
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
# set the log target
|
64
|
+
def set_target(tg)
|
65
|
+
if !tg || tg.strip.empty?
|
66
|
+
@@target = nil
|
67
|
+
elsif tg.respond_to?(:to_io)
|
68
|
+
@@target = tg
|
69
|
+
elsif(!File::exist?(tg) || ( File.file?(tg) && File.writable?(tg) ) )
|
70
|
+
@@target = File.open(tg, 'w+')
|
71
|
+
else
|
72
|
+
STDERR.puts __FILE__.dup << ': ERROR : target ' << tg << ' cannot be set'
|
73
|
+
STDERR.puts "Keeping old target " << @@target.inspect
|
74
|
+
return
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
# Output of log messages, depending on the log level set for the calling class
|
79
|
+
# and the name of the alias method which is actually called.
|
80
|
+
def log(message)
|
81
|
+
if !BasicLogging.is_muted?(self)
|
82
|
+
# how has this method been called?
|
83
|
+
mlevel = __callee__
|
84
|
+
if Levels.has_key?(mlevel) && Levels[mlevel] <= FATAL
|
85
|
+
# output only for levels equal or above the value that corresponds to
|
86
|
+
# the calling alias.
|
87
|
+
format_log( message, mlevel) if @@log_level && Levels[mlevel] >= @@log_level
|
88
|
+
else
|
89
|
+
STDERR.puts __FILE__.dup << ": ERROR : invalid log level \"" << mlevel.to_s << "\""
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
alias :debug :log
|
95
|
+
alias :info :log
|
96
|
+
alias :warn :log
|
97
|
+
alias :error :log
|
98
|
+
alias :fatal :log
|
99
|
+
|
100
|
+
attr_reader :target, :log_level
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
# 1 format_log for all loggers.
|
105
|
+
def format_log(message, mlevel)
|
106
|
+
if @@target
|
107
|
+
# indicate if a registered class or the registered object of a class is calling.
|
108
|
+
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 |")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
#---------test: execute file----------
|
114
|
+
if $0 == __FILE__
|
115
|
+
Array.extend(BasicLogging)
|
116
|
+
Array.set_level(BasicLogging::INFO)
|
117
|
+
Array.info('TEST')
|
118
|
+
ar = Array.new
|
119
|
+
ar.extend(BasicLogging)
|
120
|
+
# --- no output :
|
121
|
+
l = __LINE__
|
122
|
+
ar.debug(l.next.to_s << ': debug-test 0')
|
123
|
+
# output
|
124
|
+
ar.set_level(BasicLogging::DEBUG)
|
125
|
+
l = __LINE__
|
126
|
+
ar.debug(l.next.to_s << ': debug-test 1')
|
127
|
+
|
128
|
+
obj = Object.new
|
129
|
+
obj.extend(BasicLogging)
|
130
|
+
obj.set_level(BasicLogging::DEBUG)
|
131
|
+
puts "--------debug-----------"
|
132
|
+
obj.debug('debug')
|
133
|
+
obj.info('info')
|
134
|
+
obj.warn('warn')
|
135
|
+
obj.error('error')
|
136
|
+
obj.fatal('fatal')
|
137
|
+
puts "--------info-----------"
|
138
|
+
obj.set_level("info")
|
139
|
+
obj.debug('debug')
|
140
|
+
obj.info('info')
|
141
|
+
obj.warn('warn')
|
142
|
+
obj.error('error')
|
143
|
+
obj.fatal('fatal')
|
144
|
+
puts "--------fatal-----------"
|
145
|
+
obj.set_level("fatal")
|
146
|
+
obj.debug('debug')
|
147
|
+
obj.info('info')
|
148
|
+
obj.warn('warn')
|
149
|
+
obj.error('error')
|
150
|
+
obj.fatal('fatal')
|
151
|
+
puts "--------UNKNOWN-----------"
|
152
|
+
obj.set_level(nil)
|
153
|
+
obj.debug('debug')
|
154
|
+
obj.info('info')
|
155
|
+
obj.warn('warn')
|
156
|
+
obj.error('error')
|
157
|
+
obj.fatal('fatal')
|
158
|
+
puts " ------ Output into file ----"
|
159
|
+
obj.set_target "/tmp/test_log.log"
|
160
|
+
puts " ------ INFO -----------"
|
161
|
+
obj.set_level BasicLogging::INFO
|
162
|
+
obj.info('info output')
|
163
|
+
|
164
|
+
obj.info('info output 2')
|
165
|
+
puts "---------- invalid -------"
|
166
|
+
obj.set_target "/dev/sr0"
|
167
|
+
obj.set_level "power"
|
168
|
+
end
|
169
|
+
|
170
|
+
# EOF
|