require 'gdbm' class String def htquote gsub(/[&'"<>]/) {|c| case c when '&' then '&' when '"' then '"' when "'" then ''' when '<' then '<' when '>' then '>' else c end }.gsub( /(2[0-9]{3}-[01][0-9]-[0-3][0-9])T([012][0-9]:[0-5][0-9]:[0-6][0-9])Z?/ ) { "#$1 #$2" }.gsub(/P0Y0M0DT(\d+)H0M0S/) { "Every #$1 hours" } end end STDD = "background-color: #CCF; text-decoration: line-through double" STDM = "background-color: #CCF; text-decoration: line-through double" STAA = "background-color: #FFC; text-decoration: underline dotted" STAM = "background-color: #FFC; text-decoration: underline dotted" $prev = (ENV['PREVDATE'] || 'unknown') $now = (ENV['NOWDATE'] || Time.now.utc.strftime('%Y-%m-%dT%HZ')) $dbfnam = (ENV['CATDB'] || 'z.database') $n = 0 inkey = {} $hdr = %w( id heading OAI-date status dateStamp bounds policy format kw.temporal kw.place title poc gisc ) def dspk key, skipwis = false kq = key.htquote h = [] h.push "

Links: " unless skipwis h.push "WIS Metadata " end h.push "VolC1

\n" h.join end def dspw term case term when /\A\d{5}\z/ "#{term}" when /\A(\d{5}) [A-Z][-\w ]+\z/ "#{term}" when /\A\[(-90\.?0*:90\.?0* -180\.?0*:180\.?0*)\]\z/ "#{term} (whole globe)" when /\A\[([-+.: 0-9]+)\]\z/ "#{term}" when /\A(WMOEssential|WMOAdditional|WMOOther|NoLimitation)\z/ "#{term}" when /\A(ICAO )?(AMDAR|BUFR|CLIMAT|CREX|IAC|METAR|PILOT|SAREP|SATOB|SHIP|SIGMET|SPECI|SYNOP|TAF|TEMP)([- ][ A-Zxt.]*)?(\(FM ?\d+\))?\z/ "#{term}" when /\A(FM ?\d\d)([-A-Za-z0-9. ]*)\z/ "#{term}" else term.htquote end end def dspc s, dif = {} case s when /\A\|.*\|\z/ s.split(/\|/).map{|t| next if t.empty? if dif[t] then "#{dspw(t)}" else dspw(t) end }.join(" ") when '|' then ' ' else dspw(s) end end def dsp1 key, val, flg col = if flg == 'INS' then STAA else STDD end a = val.split(/,/, 11) return if a[1] == 'deleted' $n = $n.succ #flg,#oaiId,#oaiDate,#oaiStatus,#recordDate,#bbox,#dataPolicy,#fmt,#hours,#places,#title h = [] a.size.times {|i| s = a[i] k = $hdr[i + 2] h.push "

#{k}: #{dspc(s)}

\n" } h.unshift "

#{$n} #{flg} #{key.htquote}

\n" h.push dspk(key, flg == 'INS') h.push "
" puts h.join end def dsp2 key, oval, val a = oval.split(/,/, 11) b = val.split(/,/, 11) return if a[1] == 'deleted' and b[1] == 'deleted' return dsp1(key, oval, 'DEL') if b[1] == 'deleted' return dsp1(key, val, 'INS') if a[1] == 'deleted' return if a[1,10] == b[1,10] $n = $n.succ h = [] h.push "
" h.push "

#{$n} MODIFY #{key.htquote}

\n" a.size.times {|i| ai, bi = a[i], b[i] k = $hdr[i + 2] kd = k.downcase aa = ai.split(/\|/) ba = bi.split(/\|/) dif = {} (aa - ba).each{|t| dif[t] = true} (ba - aa).each{|t| dif[t] = true} if ai == bi then h.push "

#{k}: #{dspc(ai, dif)}

\n" else h.push "

#{k}:

" h.push "

DEL: #{dspc(ai, dif)}" h.push "

INS: #{dspc(bi, dif)}

\n" end dif = nil } h.push dspk(key) h.push "
" puts h.join end GDBM.open($dbfnam, 0666) {|hdb| puts < WIS MD Changes #{$prev.htquote}/#{$now.htquote}

WIS Metadata Changes for GTS Bulletins

Since: #{$prev.htquote}

Until: #{$now.htquote}

This is an unofficial summary made by TOYODA Eizi, compiled from WIS Discovery Metadata collected at GISC Tokyo. This is not an official notification from WMO nor JMA.

HTML for line in ARGF next if /^#/ === line key, val = line.chomp.split(/,/, 2) inkey[key] = true oval = hdb.fetch(key, nil) if oval then unless oval == val dsp2(key, oval, val) end else dsp1(key, val, 'INS') end oval = val = nil end hdb.each {|key, oval| next if inkey[key] dsp1(key, val, 'DEL') } puts <

Number of changes: #{$n}

HTML }