~ubuntu-branches/ubuntu/trusty/zonecheck/trusty-proposed

« back to all changes in this revision

Viewing changes to zc/publisher/text.rb

  • Committer: Bazaar Package Importer
  • Author(s): Stephane Bortzmeyer
  • Date: 2004-03-10 14:08:05 UTC
  • Revision ID: james.westby@ubuntu.com-20040310140805-ij55fso1e23bk8ye
Tags: upstream-2.0.3
ImportĀ upstreamĀ versionĀ 2.0.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# $Id: text.rb,v 1.39 2004/01/27 15:20:01 sdalu Exp $
 
2
 
 
3
 
4
# CONTACT     : zonecheck@nic.fr
 
5
# AUTHOR      : Stephane D'Alu <sdalu@nic.fr>
 
6
#
 
7
# CREATED     : 2002/08/02 13:58:17
 
8
# REVISION    : $Revision: 1.39 $ 
 
9
# DATE        : $Date: 2004/01/27 15:20:01 $
 
10
#
 
11
# CONTRIBUTORS: (see also CREDITS file)
 
12
#
 
13
#
 
14
# LICENSE     : GPL v2 (or MIT/X11-like after agreement)
 
15
# COPYRIGHT   : AFNIC (c) 2003
 
16
#
 
17
# This file is part of ZoneCheck.
 
18
#
 
19
# ZoneCheck is free software; you can redistribute it and/or modify it
 
20
# under the terms of the GNU General Public License as published by
 
21
# the Free Software Foundation; either version 2 of the License, or
 
22
# (at your option) any later version.
 
23
 
24
# ZoneCheck is distributed in the hope that it will be useful, but
 
25
# WITHOUT ANY WARRANTY; without even the implied warranty of
 
26
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
27
# General Public License for more details.
 
28
#
 
29
# You should have received a copy of the GNU General Public License
 
30
# along with ZoneCheck; if not, write to the Free Software Foundation,
 
31
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 
32
#
 
33
 
 
34
require 'textfmt'
 
35
require 'config'
 
36
 
 
37
module Publisher
 
38
    ##
 
39
    ##
 
40
    ##
 
41
    class Text < Template
 
42
        Mime            = "text/plain"
 
43
        MaxLineLength   = 79
 
44
 
 
45
 
 
46
        ##
 
47
        ## Rendering of XML chunks
 
48
        ##
 
49
        class XMLTransform
 
50
            attr_writer :const
 
51
 
 
52
            def initialize
 
53
                @const  = {}
 
54
            end
 
55
 
 
56
            def apply(xmlnode, var={})
 
57
                case xmlnode
 
58
                when MyXML::Node::Element
 
59
                    case xmlnode.name
 
60
                    when MsgCat::NAME, MsgCat::FAILURE, MsgCat::SUCCESS
 
61
                        do_text(xmlnode, var)
 
62
                    when MsgCat::EXPLANATION    # not displayed in tagonly
 
63
                        text = xmlnode.to_a('src').collect { |xmlsrc|
 
64
                            type  = $mc.get("tag_#{xmlsrc['type']}")
 
65
                            title = do_text(xmlsrc.child('title'))
 
66
 
 
67
                            type + ': ' + title + "\n" +
 
68
                            xmlsrc.to_a('para').collect { |xmlpara|
 
69
                                fmt_para(do_text(xmlpara, var)) }.join
 
70
                        }.join("\n")
 
71
                        ::Text::Formater.lbox(text, [ ' |', ' `', '-', ' ' ])
 
72
                    when MsgCat::DETAILS        # not displayed in tagonly
 
73
                        text = xmlnode.to_a('para').collect { |xmlpara|
 
74
                            fmt_para(do_text(xmlpara, var)) }.join("\n")
 
75
                        ::Text::Formater.lbox(text, [ ' :', ' `', '.', ' ' ])
 
76
                    else
 
77
                        do_text(xmlnode, var)
 
78
                    end
 
79
                when MyXML::Node::Text
 
80
                    xmlnode.value
 
81
                else
 
82
                    ''
 
83
                end
 
84
            end
 
85
 
 
86
            #-- [private] -----------------------------------------------
 
87
            private
 
88
            def fmt_para(text, width=MaxLineLength-7, tag='  ')
 
89
                ::Text::Formater.paragraph(text, width, tag)
 
90
            end
 
91
 
 
92
            def do_text(xmlnode, var={})
 
93
                case xmlnode
 
94
                when MyXML::Node::Element
 
95
                    case xmlnode.name
 
96
                    when 'zcvar', 'zcconst'
 
97
                        display = xmlnode['display']
 
98
                        data    = case xmlnode.name
 
99
                                  when 'zcvar'   then var
 
100
                                  when 'zcconst' then @const
 
101
                                  end
 
102
                        name    = xmlnode['name']
 
103
                        value   = data.fetch(name)
 
104
                        case display
 
105
                        when 'duration'
 
106
                            Publisher.to_bind_duration(value.to_i) 
 
107
                        else
 
108
                            value
 
109
                        end
 
110
                    else
 
111
                        xmlnode.to_a(:child).collect { |xmlchild| 
 
112
                            do_text(xmlchild, var) }.join
 
113
                    end
 
114
                when MyXML::Node::Text
 
115
                    xmlnode.value
 
116
                else
 
117
                    ''
 
118
                end
 
119
            end
 
120
        end
 
121
 
 
122
 
 
123
 
 
124
        ##
 
125
        ## Display progression information about the tests being performed.
 
126
        ##
 
127
        class Progress
 
128
            ##
 
129
            ## Progession bar implementation
 
130
            ## 
 
131
            class PBar
 
132
                BarSize = 37
 
133
 
 
134
                def initialize(output, precision)
 
135
                    @output     = output
 
136
                    @precision  = precision
 
137
                    @mutex      = Mutex::new
 
138
                    @updater    = nil
 
139
                    @l10n_unit  = $mc.get('pgr_speed_unit')
 
140
                end
 
141
                
 
142
                def start(length)
 
143
                    @length     = length
 
144
                    @starttime  = @lasttime = Time.now
 
145
                    @totaltime  = 0
 
146
                    @processed  = 0
 
147
                    @tick       = 0
 
148
 
 
149
                    @output.write $console.ctl['vi']
 
150
                    @output.print barstr
 
151
 
 
152
                    @updater    = Thread::new { 
 
153
                        last_processed = nil
 
154
                        while true
 
155
                            sleep(@precision)
 
156
                            nowtime      = Time.now
 
157
                            
 
158
                            @mutex.synchronize {
 
159
                                @totaltime      = if @lasttime == @starttime
 
160
                                                  then 0.0
 
161
                                                  else nowtime - @starttime
 
162
                                                  end
 
163
                                @lasttime       = nowtime
 
164
 
 
165
                                if @processed != last_processed
 
166
                                    @tick += 1
 
167
                                    last_processed = @processed
 
168
                                end
 
169
 
 
170
                                @output.write "\r"
 
171
                                @output.print barstr
 
172
                                @output.write $console.ctl['ce']
 
173
                                @output.flush
 
174
                            }
 
175
                        end
 
176
                    }
 
177
                end
 
178
                
 
179
                def processed(size)
 
180
                    @mutex.synchronize { @processed  += size }
 
181
                end
 
182
 
 
183
                def done
 
184
                    @mutex.synchronize { @updater.kill }
 
185
                    @output.write "\r" + $console.ctl['ce']
 
186
                    @output.flush
 
187
                end
 
188
                
 
189
                def finish
 
190
                    @output.write $console.ctl['ve']
 
191
                end
 
192
                
 
193
                protected
 
194
                def barstr
 
195
                    speed       = if @totaltime == 0.0
 
196
                                  then -1.0
 
197
                                  else @processed / @totaltime
 
198
                                  end
 
199
                    speed_s     = if speed < 0.0 
 
200
                                  then "--.--%s" % [ @l10n_unit ]
 
201
                                  else "%7.2f%s" % [ speed, @l10n_unit ]
 
202
                                  end
 
203
                    
 
204
                    if @length > 0 then
 
205
                        pct     = 100 * @processed / @length
 
206
                        eta     = if speed < 0.0 
 
207
                                  then -1
 
208
                                  else ((@length-@processed) / speed).to_i
 
209
                                  end
 
210
                        pct_s   = "%2d%%" % pct
 
211
                        eta_s   = "ETA " + sec_to_timestr(eta)
 
212
                        bar_s   = '=' * (BarSize * pct / 100) + '>'
 
213
                        
 
214
                        "%-4s[%-#{BarSize}.#{BarSize}s] %-11s %10s %12s" % [
 
215
                            pct_s, bar_s, @processed, speed_s, eta_s ]
 
216
                    else
 
217
                        ind     = @tick % (BarSize * 2 - 6)
 
218
                        pos     = if ind < BarSize - 2
 
219
                                  then ind + 1;
 
220
                                  else BarSize - (ind - BarSize + 5)
 
221
                                  end
 
222
                        bar_s   = " " * BarSize
 
223
                        bar_s[pos-1,3] = '<=>'
 
224
                        
 
225
                        "    [%s] %-11s %10s" % [ bar_s, @processed, speed_s ]
 
226
                    end
 
227
                end
 
228
                
 
229
                private
 
230
                def sec_to_timestr(sec)
 
231
                    return "--:--" if sec < 0
 
232
                    
 
233
                    hrs = sec / 3600; sec %= 3600;
 
234
                    min = sec / 60;   sec %= 60;
 
235
                    
 
236
                    if (hrs > 0)
 
237
                    then sprintf "%2d:%02d:%02d", hrs, min, sec
 
238
                    else sprintf "%2d:%02d", min, sec
 
239
                    end
 
240
                end
 
241
            end
 
242
 
 
243
 
 
244
            # Initialization
 
245
            def initialize(publisher)
 
246
                @publisher      = publisher
 
247
                @o              = publisher.output
 
248
                @counter        = if @publisher.rflag.counter && @o.tty?
 
249
                                  then PBar::new(@o, 1)
 
250
                                  else nil
 
251
                                  end
 
252
                @l10n_testing   = $mc.get('word:testing').capitalize
 
253
            end
 
254
            
 
255
            # Start progression
 
256
            def start(count)
 
257
                @counter.start(count)   if @counter
 
258
            end
 
259
            
 
260
            # Finished on success
 
261
            def done(desc)
 
262
                @counter.done           if @counter
 
263
            end
 
264
            
 
265
            # Finished on failure
 
266
            def failed(desc)
 
267
                @counter.done           if @counter
 
268
            end
 
269
            
 
270
            # Finish (finalize) output
 
271
            def finish
 
272
                @counter.finish         if @counter
 
273
            end
 
274
            
 
275
            # Process an item
 
276
            def process(checkname, ns, ip)
 
277
                # Counter
 
278
                if @counter
 
279
                    @counter.processed(1)
 
280
                end
 
281
 
 
282
                # Test description
 
283
                if @publisher.rflag.testdesc
 
284
                    xtra = if    ip then " (IP=#{ip})"
 
285
                           elsif ns then " (NS=#{ns})"
 
286
                           else          ''
 
287
                           end
 
288
                    if @publisher.rflag.tagonly
 
289
                        @o.puts "Testing: #{checkname}#{xtra}"
 
290
                    else
 
291
                        desc = @publisher.xmltrans.apply($mc.get(checkname, 
 
292
                                                MsgCat::CHECK, MsgCat::NAME))
 
293
                        @o.puts "#{@l10n_testing}: #{desc}#{xtra}"
 
294
                    end
 
295
                end
 
296
            end
 
297
        end
 
298
 
 
299
        #------------------------------------------------------------
 
300
 
 
301
        def initialize(rflag, option, ostream=$stdout)
 
302
            super(rflag, option, ostream)
 
303
            @progress   = Progress::new(self)
 
304
            @xmltrans   = XMLTransform::new
 
305
        end
 
306
 
 
307
 
 
308
        #------------------------------------------------------------
 
309
 
 
310
        def testdesc(testname, subtype)
 
311
            l10n = @xmltrans.apply($mc.get(testname, MsgCat::CHECK, subtype))
 
312
            case subtype
 
313
            when MsgCat::NAME, MsgCat::FAILURE, MsgCat::SUCCESS
 
314
                l10n += "\n"
 
315
            end
 
316
            @o.puts testname + ':'
 
317
            @o.print l10n
 
318
            @o.puts
 
319
        end
 
320
        
 
321
        def error(text)
 
322
            @o.print ::Text::Formater.paragraph(text, MaxLineLength,
 
323
                                        $mc.get('word:error').upcase+': ')
 
324
        end
 
325
 
 
326
 
 
327
        def intro(domain)
 
328
            return unless @rflag.intro
 
329
 
 
330
            l10n_zone   = $mc.get('ns_zone').upcase
 
331
            l10n_ns     = $mc.get('ns_ns'  ).upcase
 
332
            sz          = [ l10n_zone.length, l10n_ns.length+3 ].max
 
333
 
 
334
            @o.printf "%-*s : %s\n", sz, l10n_zone, domain.name
 
335
            domain.ns.each_index { |i| 
 
336
                n = domain.ns[i]
 
337
                @o.printf "%-*s : %s [%s]\n", 
 
338
                    sz, i == 0 ? "#{l10n_ns} <=" : "#{l10n_ns}  ",
 
339
                    n[0].to_s, n[1].join(', ')
 
340
            }
 
341
            @o.puts
 
342
        end
 
343
 
 
344
        def diag_start()
 
345
        end
 
346
 
 
347
        def diag_section(title)
 
348
            @o.print ::Text::Formater.title(title, MaxLineLength)
 
349
        end
 
350
 
 
351
        def diagnostic1(domainname, 
 
352
                i_count, i_unexp, w_count, w_unexp, f_count, f_unexp,
 
353
                res, severity)
 
354
 
 
355
            i_tag, w_tag, f_tag = 
 
356
                severity_description(i_unexp, w_unexp, f_unexp)
 
357
 
 
358
            summary = "%1s%03d %1s%03d %1s%03d" % [ 
 
359
                i_tag, i_count, 
 
360
                w_tag, w_count, 
 
361
                f_tag, f_count ]
 
362
 
 
363
            @o.printf "%-*s    %s\n", 
 
364
                MaxLineLength - 4 - summary.length, domainname, summary
 
365
 
 
366
            if !res.nil?
 
367
                if @rflag.tagonly
 
368
                    @o.puts "  #{res.testname}"
 
369
                    @o.puts "  #{severity}: #{res.source || 'generic'}"
 
370
                else
 
371
                    status      = Config.severity2tag(severity)
 
372
                    l10n_status = $mc.get("word:#{status}").capitalize
 
373
                    source = res.source || $mc.get('word:generic')
 
374
                    msg    = status_message(res.testname, res.desc, severity)
 
375
                    @o.puts "  #{msg}"
 
376
                    @o.puts "  #{l10n_status}: #{source}"
 
377
                end
 
378
            else
 
379
                @o.puts "  --", "  --"
 
380
            end
 
381
        end
 
382
 
 
383
        def diagnostic(severity, testname, desc, lst)
 
384
            # Testname
 
385
            if  desc.check && @rflag.testname && !@rflag.tagonly
 
386
                l10n_name = @xmltrans.apply($mc.get(testname, 
 
387
                                            MsgCat::CHECK, MsgCat::NAME))
 
388
                @o.puts "[> #{l10n_name}"
 
389
            end
 
390
 
 
391
            # Status messsage
 
392
            status_tag          = Config.severity2tag(severity)
 
393
 
 
394
            if @rflag.tagonly
 
395
                status_shorttag = severity || Config::Ok
 
396
                status = desc.error ? "[Unexpected] #{testname}" : testname
 
397
            else
 
398
                status_shorttag = $mc.get("word:#{status_tag}_id")
 
399
                status = status_message(testname, desc, severity)
 
400
            end
 
401
            @o.puts "#{status_shorttag}> #{status}"
 
402
            
 
403
            # Explanation & Details
 
404
            #  => only in case of failure (ie: not for Ok or Error)
 
405
            #     not when in 'tag only' mode
 
406
            if  desc.check && !severity.nil? && 
 
407
                    desc.error.nil? && !@rflag.tagonly
 
408
                # Explanation
 
409
                if @rflag.explain 
 
410
                    explanation = $mc.get(testname, 
 
411
                                          MsgCat::CHECK, MsgCat::EXPLANATION)
 
412
                    @o.print @xmltrans.apply(explanation) if explanation
 
413
                end
 
414
 
 
415
                # Details
 
416
                if @rflag.details && desc.details
 
417
                    details = $mc.get(testname, MsgCat::CHECK, MsgCat::DETAILS)
 
418
                    @o.print @xmltrans.apply(details, desc.details) if details
 
419
                end
 
420
            end
 
421
                
 
422
            # Elements
 
423
            lst.each { |elt| 
 
424
                elt ||= (@rflag.tagonly ? 'generic' : $mc.get('word:generic'))
 
425
                @o.print ::Text::Formater.item(elt) 
 
426
            }
 
427
 
 
428
            # Blank
 
429
            @o.puts ''
 
430
        end
 
431
            
 
432
 
 
433
        def status(domainname, i_count, w_count, f_count)
 
434
            @o.puts "==> " + super(domainname, i_count, w_count, f_count)
 
435
        end
 
436
    end
 
437
end