diff options
author | Taco Hoekwater <taco@elvenkind.com> | 2009-08-23 11:11:32 +0000 |
---|---|---|
committer | Taco Hoekwater <taco@elvenkind.com> | 2009-08-23 11:11:32 +0000 |
commit | 8fc3039c82d48605b5ca8b2eda3f4fdd755681e1 (patch) | |
tree | 3cd9bbdd599bc4d1ac0409e167fee2136e4c0ec9 /Master/texmf-dist/scripts/context/ruby | |
parent | 850fc99b7cd3ae7a20065531fe866ff7bae642ec (diff) |
this is context 2009.08.19 17:10
git-svn-id: svn://tug.org/texlive/trunk@14827 c570f23f-e606-0410-a88d-b1316a301751
Diffstat (limited to 'Master/texmf-dist/scripts/context/ruby')
30 files changed, 438 insertions, 5490 deletions
diff --git a/Master/texmf-dist/scripts/context/ruby/base/exa.rb b/Master/texmf-dist/scripts/context/ruby/base/exa.rb index 5a094351ec5..7ba990cf900 100644 --- a/Master/texmf-dist/scripts/context/ruby/base/exa.rb +++ b/Master/texmf-dist/scripts/context/ruby/base/exa.rb @@ -3,8 +3,9 @@ # tex.setup.setuplayout.width.[integer|real|dimension|string|key] # tex.[mp]var.whatever.width.[integer|real|dimension|string|key] -require 'ftools' -require 'md5' +require 'fileutils' +# require 'ftools' +require 'digest/md5' # this can become a lua thing @@ -40,7 +41,7 @@ module ExaEncrypt pre, password, post = $1, $2, $3 unless password =~ /MD5:/i then done = true - password = "MD5:" + MD5.new(password).hexdigest.upcase + password = "MD5:" + Digest::MD5.hexdigest(password).upcase end "#{pre}#{password}#{post}" end @@ -49,7 +50,7 @@ module ExaEncrypt attributes, password = $1, $2 unless password =~ /^([0-9A-F][0-9A-F])+$/ then done = true - password = MD5.new(password).hexdigest.upcase + password = Digest::MD5.hexdigest(password).upcase attributes = " encryption='md5'#{attributes}" end "<exa:password#{attributes}>#{password}</exa:password>" diff --git a/Master/texmf-dist/scripts/context/ruby/base/file.rb b/Master/texmf-dist/scripts/context/ruby/base/file.rb index 39bb7d46731..1aeac5fd697 100644 --- a/Master/texmf-dist/scripts/context/ruby/base/file.rb +++ b/Master/texmf-dist/scripts/context/ruby/base/file.rb @@ -8,7 +8,8 @@ # info : j.hagen@xs4all.nl # www : www.pragma-ade.com -require 'ftools' +require 'fileutils' +# require 'ftools' class File @@ -110,7 +111,7 @@ class File def File.silentcopy(oldname,newname) return if File.expand_path(oldname) == File.expand_path(newname) - File.makedirs(File.dirname(newname)) rescue false + FileUtils.makedirs(File.dirname(newname)) rescue false File.copy(oldname,newname) rescue false end @@ -123,7 +124,7 @@ class File begin File.rename(oldname,newname) rescue - File.makedirs(File.dirname(newname)) rescue false + FileUtils.makedirs(File.dirname(newname)) rescue false File.copy(oldname,newname) rescue false end end diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpse.rb b/Master/texmf-dist/scripts/context/ruby/base/kpse.rb index 0e185b5b8d7..0f986878413 100644 --- a/Master/texmf-dist/scripts/context/ruby/base/kpse.rb +++ b/Master/texmf-dist/scripts/context/ruby/base/kpse.rb @@ -13,6 +13,7 @@ # todo: web2c vs miktex module and include in kpse require 'rbconfig' +require 'fileutils' # beware $engine is lowercase in kpse # @@ -185,6 +186,7 @@ module Kpse return results end + def Kpse.formatpaths # maybe we should check for writeability unless @@paths.key?('formatpaths') then @@ -272,7 +274,7 @@ module Kpse unless done then formatpaths.each do |fp| fpp = fp.sub(/#{engine}\/*$/o,'') - File.makedirs(fpp) rescue false # maybe we don't have an path yet + FileUtils.makedirs(fpp) rescue false # maybe we don't have an path yet if FileTest.directory?(fpp) && FileTest.writable?(fpp) then # use this path formatpath, done = fp.dup, true @@ -285,12 +287,12 @@ module Kpse end end # needed ! - File.makedirs(formatpath) rescue false + FileUtils.makedirs(formatpath) rescue false # fall back to current path formatpath = '.' if formatpath.empty? || ! FileTest.writable?(formatpath) # append engine but prevent duplicates formatpath = File.join(formatpath.sub(/\/*#{engine}\/*$/,''), engine) if enginepath - File.makedirs(formatpath) rescue false + FileUtils.makedirs(formatpath) rescue false setpath(engine,formatpath) # ENV['engine'] = savedengine end diff --git a/Master/texmf-dist/scripts/context/ruby/base/kpsetrees.rb b/Master/texmf-dist/scripts/context/ruby/base/kpsetrees.rb deleted file mode 100644 index 8e3fb20f854..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/base/kpsetrees.rb +++ /dev/null @@ -1,65 +0,0 @@ -require 'monitor' -require 'base/kpsefast' - -class KpseTrees < Monitor - - def initialize - @trees = Hash.new - @monitor = Monitor.new - end - - def choose(filenames,environment) - current = filenames.join('|') - # @monitor do - unless @trees[current] then - puts "loading tree #{current}" - @trees[current] = KpseFast.new - @trees[current].push_environment(environment) - @trees[current].load_cnf(filenames) - @trees[current].expand_variables - @trees[current].load_lsr - end - puts "enabling tree #{current}" - # end - current - end - - def set(tree,key,value) - case key - when 'progname' then @trees[tree].progname = value - when 'engine' then @trees[tree].engine = value - when 'format' then @trees[tree].format = value - end - end - def load_cnf(tree) - @trees[tree].load_cnf - end - def load_lsr(tree) - @trees[tree].load_lsr - end - def expand_variables(tree) - @trees[tree].expand_variables - end - def expand_braces(tree,str) - @trees[tree].expand_braces(str) - end - def expand_path(tree,str) - @trees[tree].expand_path(str) - end - def expand_var(tree,str) - @trees[tree].expand_var(str) - end - def show_path(tree,str) - @trees[tree].show_path(str) - end - def var_value(tree,str) - @trees[tree].var_value(str) - end - def find_file(tree,filename) - @trees[tree].find_file(filename) - end - def find_files(tree,filename,first) - @trees[tree].find_files(filename,first) - end - -end diff --git a/Master/texmf-dist/scripts/context/ruby/base/state.rb b/Master/texmf-dist/scripts/context/ruby/base/state.rb index 4b208812875..76ef50b2563 100644 --- a/Master/texmf-dist/scripts/context/ruby/base/state.rb +++ b/Master/texmf-dist/scripts/context/ruby/base/state.rb @@ -1,4 +1,4 @@ -require "md5" +require 'digest/md5' # todo: register omissions per file @@ -57,7 +57,7 @@ class FileState begin if FileTest.file?(filename) && (data = IO.read(filename)) then data.gsub!(/\n.*?(#{[omit].flatten.join('|')}).*?\n/) do "\n" end if omit - sum = MD5.new(data).hexdigest.upcase + sum = Digest::MD5.hexdigest(data).upcase end rescue sum = '' diff --git a/Master/texmf-dist/scripts/context/ruby/base/tex.rb b/Master/texmf-dist/scripts/context/ruby/base/tex.rb index 582ff640c6e..23db7f1e872 100644 --- a/Master/texmf-dist/scripts/context/ruby/base/tex.rb +++ b/Master/texmf-dist/scripts/context/ruby/base/tex.rb @@ -16,6 +16,8 @@ # report ? +require 'fileutils' + require 'base/variables' require 'base/kpse' require 'base/system' @@ -67,28 +69,26 @@ class TEX include Variables - @@texengines = Hash.new - @@mpsengines = Hash.new - @@backends = Hash.new - @@mappaths = Hash.new - @@runoptions = Hash.new - @@tcxflag = Hash.new - @@draftoptions = Hash.new - @@texformats = Hash.new - @@mpsformats = Hash.new - @@prognames = Hash.new - @@texmakestr = Hash.new - @@texprocstr = Hash.new - @@mpsmakestr = Hash.new - @@mpsprocstr = Hash.new - - @@texmethods = Hash.new - @@mpsmethods = Hash.new - - @@pdftex = 'pdftex' # new default, pdfetex is gone - - @@luafiles = "luafiles.tmp" - @@luatarget = "lua/context" + @@texengines = Hash.new + @@mpsengines = Hash.new + @@backends = Hash.new + @@mappaths = Hash.new + @@runoptions = Hash.new + @@tcxflag = Hash.new + @@draftoptions = Hash.new + @@synctexcoptions = Hash.new + @@texformats = Hash.new + @@mpsformats = Hash.new + @@prognames = Hash.new + @@texmakestr = Hash.new + @@texprocstr = Hash.new + @@mpsmakestr = Hash.new + @@mpsprocstr = Hash.new + @@texmethods = Hash.new + @@mpsmethods = Hash.new + @@pdftex = 'pdftex' # new default, pdfetex is gone + @@luafiles = "luafiles.tmp" + @@luatarget = "lua/context" @@platformslash = if System.unix? then "\\\\" else "\\" end @@ -112,8 +112,8 @@ class TEX ['tex','standard'] .each do |b| @@mappaths[b] = 'dvips' end ['pdftex','pdfetex'] .each do |b| @@mappaths[b] = 'pdftex' end - ['aleph','omega','xetex','petex'] .each do |b| @@mappaths[b] = 'dvipdfm' end - ['dvipdfm', 'dvipdfmx', 'xdvipdfmx'] .each do |b| @@mappaths[b] = 'dvipdfm' end + ['aleph','omega','xetex','petex'] .each do |b| @@mappaths[b] = 'dvipdfmx' end + ['dvipdfm', 'dvipdfmx', 'xdvipdfmx'] .each do |b| @@mappaths[b] = 'dvipdfmx' end ['xdv','xdv2pdf'] .each do |b| @@mappaths[b] = 'dvips' end # todo norwegian (no) @@ -124,14 +124,16 @@ class TEX ['cont-de','de','german'] .each do |f| @@texformats[f] = 'cont-de' end ['cont-it','it','italian'] .each do |f| @@texformats[f] = 'cont-it' end ['cont-fr','fr','french'] .each do |f| @@texformats[f] = 'cont-fr' end - ['cont-cz','cz','czech'] .each do |f| @@texformats[f] = 'cont-cz' end + ['cont-cs','cs','cont-cz','cz','czech'] .each do |f| @@texformats[f] = 'cont-cs' end ['cont-ro','ro','romanian'] .each do |f| @@texformats[f] = 'cont-ro' end - ['cont-uk','uk','british'] .each do |f| @@texformats[f] = 'cont-uk' end + ['cont-gb','gb','cont-uk','uk','british'] .each do |f| @@texformats[f] = 'cont-gb' end + ['cont-pe','pe','persian'] .each do |f| @@texformats[f] = 'cont-pe' end + ['cont-xp','xp','experimental'] .each do |f| @@texformats[f] = 'cont-xp' end ['mptopdf'] .each do |f| @@texformats[f] = 'mptopdf' end ['latex'] .each do |f| @@texformats[f] = 'latex.ltx' end - ['plain','mpost'] .each do |f| @@mpsformats[f] = 'plain' end + ['plain','mpost'] .each do |f| @@mpsformats[f] = 'mpost' end ['metafun','context','standard'] .each do |f| @@mpsformats[f] = 'metafun' end ['pdftex','pdfetex','aleph','omega','petex', @@ -141,7 +143,8 @@ class TEX ['plain','default','standard','mptopdf'] .each do |f| @@texmethods[f] = 'plain' end ['cont-en','cont-nl','cont-de','cont-it', - 'cont-fr','cont-cz','cont-ro','cont-uk'] .each do |f| @@texmethods[f] = 'context' end + 'cont-fr','cont-cs','cont-ro','cont-gb', + 'cont-pe','cont-xp'] .each do |f| @@texmethods[f] = 'context' end ['latex','pdflatex'] .each do |f| @@texmethods[f] = 'latex' end ['plain','default','standard'] .each do |f| @@mpsmethods[f] = 'plain' end @@ -151,28 +154,31 @@ class TEX @@mpsmakestr['plain'] = @@platformslash + "dump" ['cont-en','cont-nl','cont-de','cont-it', - 'cont-fr','cont-cz','cont-ro','cont-uk'] .each do |f| @@texprocstr[f] = @@platformslash + "emergencyend" end - - @@runoptions['aleph'] = ['--8bit'] - @@runoptions['luatex'] = ['--file-line-error'] - @@runoptions['mpost'] = ['--8bit'] - @@runoptions['pdfetex'] = ['--8bit'] # obsolete - @@runoptions['pdftex'] = ['--8bit'] # pdftex is now pdfetex - # @@runoptions['petex'] = [] - @@runoptions['xetex'] = ['--8bit','-output-driver="xdvipdfmx -E -d 4 -V 5"'] + 'cont-fr','cont-cs','cont-ro','cont-gb', + 'cont-pe','cont-xp'] .each do |f| @@texprocstr[f] = @@platformslash + "emergencyend" end + + @@runoptions['aleph'] = ['--8bit'] + @@runoptions['luatex'] = ['--file-line-error'] + @@runoptions['mpost'] = ['--8bit'] + @@runoptions['pdfetex'] = ['--8bit'] # obsolete + @@runoptions['pdftex'] = ['--8bit'] # pdftex is now pdfetex + # @@runoptions['petex'] = [] + @@runoptions['xetex'] = ['--8bit','-output-driver="xdvipdfmx -E -d 4 -V 5"'] + @@draftoptions['pdftex'] = ['--draftmode'] + @@synctexcoptions['pdftex'] = ['--synctex=1'] + @@synctexcoptions['luatex'] = ['--synctex=1'] + @@synctexcoptions['xetex'] = ['--synctex=1'] @@tcxflag['aleph'] = true @@tcxflag['luatex'] = false - @@tcxflag['mpost'] = true + @@tcxflag['mpost'] = false @@tcxflag['pdfetex'] = true @@tcxflag['pdftex'] = true @@tcxflag['petex'] = false @@tcxflag['xetex'] = false - @@draftoptions['pdftex'] = ['--draftmode'] - - @@booleanvars = [ - 'batchmode', 'nonstopmode', 'fast', 'fastdisabled', 'silentmode', 'final', + @@mainbooleanvars = [ + 'batchmode', 'nonstopmode', 'fast', 'final', 'paranoid', 'notparanoid', 'nobanner', 'once', 'allpatterns', 'draft', 'nompmode', 'nomprun', 'automprun', 'combine', 'nomapfiles', 'local', @@ -184,19 +190,20 @@ class TEX 'globalfile', 'autopath', 'purge', 'purgeall', 'keep', 'autopdf', 'xpdf', 'simplerun', 'verbose', 'nooptionfile', 'nobackend', 'noctx', 'utfbom', - 'mkii', + 'mkii','mkiv', + 'synctex', ] - @@stringvars = [ + @@mainstringvars = [ 'modefile', 'result', 'suffix', 'response', 'path', 'filters', 'usemodules', 'environments', 'separation', 'setuppath', 'arguments', 'input', 'output', 'randomseed', 'modes', 'mode', 'filename', 'ctxfile', 'printformat', 'paperformat', 'paperoffset', 'timeout', 'passon' ] - @@standardvars = [ + @@mainstandardvars = [ 'mainlanguage', 'bodyfont', 'language' ] - @@knownvars = [ + @@mainknownvars = [ 'engine', 'distribution', 'texformats', 'mpsformats', 'progname', 'interface', 'runs', 'backend' ] @@ -205,29 +212,31 @@ class TEX @@extrastringvars = [] def booleanvars - [@@booleanvars,@@extrabooleanvars].flatten.uniq + [@@mainbooleanvars,@@extrabooleanvars].flatten.uniq end def stringvars - [@@stringvars,@@extrastringvars].flatten.uniq + [@@mainstringvars,@@extrastringvars].flatten.uniq end def standardvars - [@@standardvars].flatten.uniq + [@@mainstandardvars].flatten.uniq end def knownvars - [@@knownvars].flatten.uniq + [@@mainknownvars].flatten.uniq end def allbooleanvars - [@@booleanvars,@@extrabooleanvars].flatten.uniq + [@@mainbooleanvars,@@extrabooleanvars].flatten.uniq end def allstringvars - [@@stringvars,@@extrastringvars,@@standardvars,@@knownvars].flatten.uniq + [@@mainstringvars,@@extrastringvars,@@mainstandardvars,@@mainknownvars].flatten.uniq end def setextrastringvars(vars) - @@extrastringvars << vars + # @@extrastringvars << vars -- problems in 1.9 + @@extrastringvars = [@@extrastringvars,vars].flatten end def setextrabooleanvars(vars) - @@extrabooleanvars << vars + # @@extrabooleanvars << vars -- problems in 1.9 + @@extrabooleanvars = [@@extrabooleanvars,vars].flatten end # def jobvariables(names=nil) @@ -378,6 +387,7 @@ class TEX def runoptions(engine) options = if getvariable('draft') then @@draftoptions[engine] else [] end + options = if getvariable('synctex') then @@synctexcoptions[engine] else [] end begin if str = getvariable('passon') then options = [options,str.split(' ')].flatten @@ -577,7 +587,7 @@ class TEX if data = (IO.readlines(@@luafiles) rescue nil) then report("compiling lua files (using #{File.expand_path(@@luafiles)})") begin - File.makedirs(@@luatarget) rescue false + FileUtils.makedirs(@@luatarget) rescue false data.each do |line| luafile = line.chomp lucfile = File.basename(luafile).gsub(/\..*?$/,'') + ".luc" @@ -640,10 +650,14 @@ class TEX report("using tex format path #{texformatpath}") Dir.chdir(texformatpath) rescue false if FileTest.writable?(texformatpath) then - if texformats.length > 0 then - makeuserfile - makeresponsefile - end + # from now on we no longer support this; we load + # all patterns and if someone wants another + # interface language ... cook up a fmt or usr file + # + # if texformats.length > 0 then + # makeuserfile + # makeresponsefile + # end if texengine == 'luatex' then cleanupluafiles texformats.each do |texformat| @@ -679,7 +693,8 @@ class TEX mpsformats.each do |mpsformat| report("generating mps format #{mpsformat}") progname = validprogname([getvariable('progname'),mpsformat,mpsengine]) - if not runcommand([quoted(mpsengine),prognameflag(progname),iniflag,tcxflag(mpsengine),runoptions(mpsengine),mpsformat,mpsmakeextras(mpsformat)]) then + # if not runcommand([quoted(mpsengine),prognameflag(progname),iniflag,tcxflag(mpsengine),runoptions(mpsengine),mpsformat,mpsmakeextras(mpsformat)]) then + if not runcommand([quoted(mpsengine),prognameflag(progname),iniflag,runoptions(mpsengine),mpsformat,mpsmakeextras(mpsformat)]) then setvariable('error','no format made') end end @@ -879,7 +894,7 @@ class TEX def scantexpreamble(filename) begin - if FileTest.file?(filename) and tex = File.open(filename) then + if FileTest.file?(filename) and tex = File.open(filename,'rb') then bomdone = false while str = tex.gets and str.chomp! do unless bomdone then @@ -925,7 +940,7 @@ end end def scantexcontent(filename) - if FileTest.file?(filename) and tex = File.open(filename) then + if FileTest.file?(filename) and tex = File.open(filename,'rb') then while str = tex.gets do case str.chomp when /^\%/o then @@ -1002,7 +1017,11 @@ end tmp << "\\starttext\n" if forcexml then # tmp << checkxmlfile(rawname) - tmp << "\\processXMLfilegrouped{#{rawname}}\n" + if getvariable('mkiv') then + tmp << "\\xmlprocess{\\xmldocument}{#{rawname}}{}\n" + else + tmp << "\\processXMLfilegrouped{#{rawname}}\n" + end else tmp << "\\processfile{#{rawname}}\n" end @@ -1056,7 +1075,7 @@ end end def checkxmlfile(rawname) - if FileTest.file?(rawname) && (xml = File.open(rawname)) then + if FileTest.file?(rawname) && (xml = File.open(rawname,'rb')) then xml.each do |line| case line when /<\?context\-directive\s+(\S+)\s+(\S+)\s+(\S+)\s*(.*?)\s*\?>/o then @@ -1322,12 +1341,9 @@ class TEX # local handies opt << "\% #{topname}\n" opt << "\\unprotect\n" - if getvariable('utfbom') then - opt << "\\enableregime[utf]" - end - opt << "\\setupsystem[\\c!n=#{kindofrun},\\c!m=#{currentrun}]\n" - progname = validprogname(['metafun']) # [getvariable('progname'),mpsformat,mpsengine] - opt << "\\def\\MPOSTformatswitch\{#{prognameflag(progname)} #{formatflag('mpost')}=\}\n" + # + # feedback and basic control + # if getvariable('batchmode') then opt << "\\batchmode\n" end @@ -1337,6 +1353,21 @@ class TEX if getvariable('paranoid') then opt << "\\def\\maxreadlevel{1}\n" end + if getvariable('nomapfiles') then + opt << "\\disablemapfiles\n" + end + if getvariable('nompmode') || getvariable('nomprun') || getvariable('automprun') then + opt << "\\runMPgraphicsfalse\n" + end + if getvariable('utfbom') then + opt << "\\enableregime[utf]" + end + progname = validprogname(['metafun']) # [getvariable('progname'),mpsformat,mpsengine] + opt << "\\def\\MPOSTformatswitch\{#{prognameflag(progname)} #{formatflag('mpost')}=\}\n" + # + # process info + # + opt << "\\setupsystem[\\c!n=#{kindofrun},\\c!m=#{currentrun}]\n" if (str = File.unixfied(getvariable('modefile'))) && ! str.empty? then opt << "\\readlocfile{#{str}}{}{}\n" end @@ -1353,6 +1384,35 @@ class TEX if (str = getvariable('mainlanguage').downcase) && ! str.empty? && ! str.standard? then opt << "\\setuplanguage[#{str}]\n" end + if (str = getvariable('arguments')) && ! str.empty? then + opt << "\\setupenv[#{str}]\n" + end + if (str = getvariable('setuppath')) && ! str.empty? then + opt << "\\setupsystem[\\c!directory=\{#{str}\}]\n" + end + if (str = getvariable('randomseed')) && ! str.empty? then + report("using randomseed #{str}") + opt << "\\setupsystem[\\c!random=#{str}]\n" + end + if (str = getvariable('input')) && ! str.empty? then + opt << "\\setupsystem[inputfile=#{str}]\n" + else + opt << "\\setupsystem[inputfile=#{rawname}]\n" + end + # + # modes + # + # we handle both "--mode" and "--modes", else "--mode" is mapped onto "--modefile" + if (str = getvariable('modes')) && ! str.empty? then + opt << "\\enablemode[#{str}]\n" + end + if (str = getvariable('mode')) && ! str.empty? then + opt << "\\enablemode[#{str}]\n" + end + # + # options + # + opt << "\\startsetups *runtime:options\n" if str = validbackend(getvariable('backend')) then opt << "\\setupoutput[#{str}]\n" elsif str = validbackend(getvariable('output')) then @@ -1361,21 +1421,9 @@ class TEX if getvariable('color') then opt << "\\setupcolors[\\c!state=\\v!start]\n" end - if getvariable('nompmode') || getvariable('nomprun') || getvariable('automprun') then - opt << "\\runMPgraphicsfalse\n" - end - if getvariable('fast') && ! getvariable('fastdisabled') then - opt << "\\fastmode\n" - end - if getvariable('silentmode') then - opt << "\\silentmode\n" - end if (str = getvariable('separation')) && ! str.empty? then opt << "\\setupcolors[\\c!split=#{str}]\n" end - if (str = getvariable('setuppath')) && ! str.empty? then - opt << "\\setupsystem[\\c!directory=\{#{str}\}]\n" - end if (str = getvariable('paperformat')) && ! str.empty? && ! str.standard? then if str =~ /^([a-z]+\d+)([a-z]+\d+)$/io then # A5A4 A4A3 A2A1 ... opt << "\\setuppapersize[#{$1.upcase}][#{$2.upcase}]\n" @@ -1392,9 +1440,6 @@ class TEX if getvariable('centerpage') then opt << "\\setuplayout[\\c!location=\\v!middle,\\c!marking=\\v!on]\n" end - if getvariable('nomapfiles') then - opt << "\\disablemapfiles\n" - end if getvariable('noarrange') then opt << "\\setuparranging[\\v!disable]\n" elsif getvariable('arrange') then @@ -1412,26 +1457,6 @@ class TEX end opt << "\\setuparranging[#{arrangement.flatten.join(',')}]\n" if arrangement.size > 0 end - # we handle both "--mode" and "--modes", else "--mode" is - # mapped onto "--modefile" - if (str = getvariable('modes')) && ! str.empty? then - opt << "\\enablemode[#{str}]\n" - end - if (str = getvariable('mode')) && ! str.empty? then - opt << "\\enablemode[#{str}]\n" - end - if (str = getvariable('arguments')) && ! str.empty? then - opt << "\\setupenv[#{str}]\n" - end - if (str = getvariable('randomseed')) && ! str.empty? then - report("using randomseed #{str}") - opt << "\\setupsystem[\\c!random=#{str}]\n" - end - if (str = getvariable('input')) && ! str.empty? then - opt << "\\setupsystem[inputfile=#{str}]\n" - else - opt << "\\setupsystem[inputfile=#{rawname}]\n" - end if (str = getvariable('pages')) && ! str.empty? then if str.downcase == 'odd' then opt << "\\chardef\\whichpagetoshipout=1\n" @@ -1452,14 +1477,18 @@ class TEX opt << "\\def\\pagestoshipout\{#{pagelist.join(',')}\}\n"; end end - opt << "\\protect\n"; - # begin getvariable('modes' ).split(',').uniq.each do |e| opt << "\\enablemode [#{e}]\n" end ; rescue ; end + opt << "\\stopsetups\n" + # + # styles and modules + # + opt << "\\startsetups *runtime:modules\n" begin getvariable('filters' ).split(',').uniq.each do |f| opt << "\\useXMLfilter[#{f}]\n" end ; rescue ; end begin getvariable('usemodules' ).split(',').uniq.each do |m| opt << "\\usemodule [#{m}]\n" end ; rescue ; end begin getvariable('environments').split(',').uniq.each do |e| opt << "\\environment #{e} \n" end ; rescue ; end - # this will become: - # begin getvariable('environments').split(',').uniq.each do |e| opt << "\\useenvironment[#{e}]\n" end ; rescue ; end - opt << "\\endinput\n" + opt << "\\stopsetups\n" + # + opt << "\\protect \\endinput\n" + # opt.close else report("unable to write option file #{topname}") @@ -1572,7 +1601,9 @@ end if mpsengine && mpsformat then ENV["MPXCOMMAND"] = "0" unless mpx progname = validprogname([getvariable('progname'),mpsformat,mpsengine]) - runcommand([quoted(mpsengine),prognameflag(progname),formatflag(mpsengine,mpsformat),tcxflag(mpsengine),runoptions(mpsengine),mpname,mpsprocextras(mpsformat)]) + mpname.gsub!(/\.mp$/,"") # temp bug in mp + # runcommand([quoted(mpsengine),prognameflag(progname),formatflag(mpsengine,mpsformat),tcxflag(mpsengine),runoptions(mpsengine),mpname,mpsprocextras(mpsformat)]) + runcommand([quoted(mpsengine),prognameflag(progname),formatflag(mpsengine,mpsformat),runoptions(mpsengine),mpname,mpsprocextras(mpsformat)]) true else false @@ -1582,7 +1613,7 @@ end def runtexmp(filename,filetype='',purge=true) checktestversion mpname = File.suffixed(filename,filetype,'mp') - if File.atleast?(mpname,25) then + if File.atleast?(mpname,10) then # first run needed File.silentdelete(File.suffixed(mpname,'mpt')) doruntexmp(mpname,nil,true,purge) @@ -1620,7 +1651,7 @@ end end def runtexutil(filename=[], options=['--ref','--ij','--high'], old=false) - filename.each do |fname| + [filename].flatten.each do |fname| if old then Kpse.runscript('texutil',fname,options) else @@ -1980,7 +2011,7 @@ end end if true then # autopurge begin - File.open(File.suffixed(rawbase, 'tuo')) do |f| + File.open(File.suffixed(rawbase, 'tuo'),'rb') do |f| ok = 0 f.each do |line| case ok @@ -2058,7 +2089,7 @@ end setvariable('mp.line','') setvariable('mp.error','') if mpdata = File.silentread(mpname) then - mpdata.gsub!(/^\%.*\n/o,'') + # mpdata.gsub!(/^\%.*\n/o,'') File.silentrename(mpname,mpcopy) texfound = mergebe || (mpdata =~ /btex .*? etex/mo) if mp = openedfile(mpname) then @@ -2075,10 +2106,11 @@ end mp << mergebe['0'] if mergebe.key?('0') end end - mp << MPTools::splitmplines(mpdata) - mp << "\n" - mp << "end" + # mp << MPTools::splitmplines(mpdata) + mp << mpdata mp << "\n" + # mp << "end" + # mp << "\n" mp.close end processmpx(mpname,true,true,purge) if texfound @@ -2090,7 +2122,10 @@ end options = '' end # todo plain|mpost|metafun - ok = runmp(mpname) + begin + ok = runmp(mpname) + rescue + end if f = File.silentopen(File.suffixed(mpname,'log')) then while str = f.gets do if str =~ /^l\.(\d+)\s(.*?)\n/o then @@ -2174,30 +2209,57 @@ end end def checkmpgraphics(mpname) + # in practice the checksums will differ because of multiple instances + # ok, we could save the mpy/mpo files by number, but not now mpoptions = '' if getvariable('makempy') then mpoptions += " --makempy " end + mponame = File.suffixed(mpname,'mpo') + mpyname = File.suffixed(mpname,'mpy') + pdfname = File.suffixed(mpname,'pdf') + tmpname = File.suffixed(mpname,'tmp') if getvariable('mpyforce') || getvariable('forcempy') then mpoptions += " --force " else - mponame = File.suffixed(mpname,'mpo') - mpyname = File.suffixed(mpname,'mpy') return false unless File.atleast?(mponame,32) mpochecksum = FileState.new.checksum(mponame) return false if mpochecksum.empty? # where does the checksum get into the file? # maybe let texexec do it? # solution: add one if not present or update when different - if f = File.silentopen(mpyname) then - str = f.gets.chomp - f.close - if str =~ /^\%\s*mpochecksum\s*\:\s*(\d+)/o then - return false if mpochecksum == $1 + begin + mpydata = IO.read(mpyname) + if mpydata then + if mpydata =~ /^\%\s*mpochecksum\s*\:\s*([A-Z0-9]+)$/mo then + checksum = $1 + if mpochecksum == checksum then + return false + end + end + end + rescue + # no file + end + end + # return Kpse.runscript('makempy',mpname) + # only pdftex + flags = ['--noctx','--process','--batch','--once'] + result = runtexexec([mponame], flags, 1) + runcommand(["pstoedit","-ssp -dt -f mpost", pdfname,tmpname]) + tmpdata = IO.read(tmpname) + if tmpdata then + if mpy = openedfile(mpyname) then + mpy << "% mpochecksum: #{mpochecksum}\n" + tmpdata.scan(/beginfig(.*?)endfig/mo) do |s| + mpy << "begingraphictextfig#{s}endgraphictextfig\n" end + mpy.close() end end - return Kpse.runscript('makempy',mpname) + File.silentdelete(tmpname) + File.silentdelete(pdfname) + return true end def checkmplabels(mpname) diff --git a/Master/texmf-dist/scripts/context/ruby/base/texutil.rb b/Master/texmf-dist/scripts/context/ruby/base/texutil.rb index 063f67f2d38..868e3ca1625 100644 --- a/Master/texmf-dist/scripts/context/ruby/base/texutil.rb +++ b/Master/texmf-dist/scripts/context/ruby/base/texutil.rb @@ -475,18 +475,37 @@ class TeXUtil @@debug = false def initialize(t, c, k, d) - @type, @command, @key, @sortkey, @data = t, c, k, k, d + @type, @command, @key, @sortkey, @data = t, c, k, c, d end attr_reader :type, :command, :key, :data attr_reader :sortkey attr_writer :sortkey + # def build(sorter) + # if @key then + # @sortkey = sorter.normalize(sorter.tokenize(@sortkey)) + # @sortkey = sorter.remap(sorter.simplify(@key.downcase)) # ?? + # if @sortkey.empty? then + # @sortkey = sorter.remap(@command.downcase) + # end + # else + # @key = "" + # @sortkey = "" + # end + # end + def build(sorter) - @sortkey = sorter.normalize(sorter.tokenize(@sortkey)) - @sortkey = sorter.remap(sorter.simplify(@key.downcase)) # ?? - if @sortkey.empty? then - @sortkey = sorter.remap(@command.downcase) + if @sortkey and not @sortkey.empty? then + @sortkey = sorter.normalize(sorter.tokenize(@sortkey)) + @sortkey = sorter.remap(sorter.simplify(@sortkey.downcase)) # ?? + end + if not @sortkey or @sortkey.empty? then + @sortkey = sorter.normalize(sorter.tokenize(@key)) + @sortkey = sorter.remap(sorter.simplify(@sortkey.downcase)) # ?? + end + if not @sortkey or @sortkey.empty? then + @sortkey = @key.dup end end @@ -618,6 +637,9 @@ class TeXUtil if special then @sortkey = "#{@@specialsymbol}#{@sortkey}" end + if @realpage == 0 then + @realpage = 999999 + end @sortkey = [ @sortkey.downcase, @sortkey, @@ -687,7 +709,6 @@ class TeXUtil alphaclass, alpha = '', '' @@savedhowto, @@savedfrom, @@savedto, @@savedentry = '', '', '', '' if @@debug then - # if true then list.each do |entry| handle << "% [#{entry.sortkey.gsub(/#{@@split}/o,'] [')}]\n" end @@ -773,7 +794,8 @@ class TeXUtil copied = true end @nofentries += 1 if copied - if entry.realpage.to_i == 0 then + # if entry.realpage.to_i == 0 then + if entry.realpage.to_i == 999999 then Register.flushsavedline(handle) handle << "\\registersee{#{entry.type}}{#{entry.pagehowto},#{entry.texthowto}}{#{entry.seetoo}}{#{entry.page}}%\n" ; lastpage, lastrealpage = entry.page, entry.realpage @@ -1006,7 +1028,7 @@ class TeXUtil tuifile = File.suffixed(filename,'tui') if FileTest.file?(tuifile) then report("parsing file #{tuifile}") - if f = open(tuifile) then + if f = File.open(tuifile,'rb') then f.each do |line| case line.chomp when /^f (.*)$/o then @plugins.reader('MyFiles', $1.splitdata) diff --git a/Master/texmf-dist/scripts/context/ruby/base/tool.rb b/Master/texmf-dist/scripts/context/ruby/base/tool.rb index 5ccedfec1c1..abf0d5ed05c 100644 --- a/Master/texmf-dist/scripts/context/ruby/base/tool.rb +++ b/Master/texmf-dist/scripts/context/ruby/base/tool.rb @@ -24,10 +24,15 @@ module Tool t = Time.now u = t.usec.to_s % [1..2] [0..3] pth = t.strftime("#{mainpath}%Y%m%d-%H%M%S-#{u}-#{Process.pid}") - if pth == $constructedtempdir - # sleep(0.01) - retry - end + # + # problems with 1.9 + # + # if pth == $constructedtempdir + # # sleep(0.01) + # retry + # end + pth == $constructedtempdir + # Dir.mkdir(pth) if create $constructedtempdir = pth return pth @@ -216,7 +221,7 @@ module Tool def Tool.checksuffix(old) - return old unless test(?f,old) + return old unless FileTest.file?(old) new = old diff --git a/Master/texmf-dist/scripts/context/ruby/ctxtools.rb b/Master/texmf-dist/scripts/context/ruby/ctxtools.rb index 00d2b494bb0..67baaab39c4 100644 --- a/Master/texmf-dist/scripts/context/ruby/ctxtools.rb +++ b/Master/texmf-dist/scripts/context/ruby/ctxtools.rb @@ -56,7 +56,8 @@ require 'base/file' require 'rexml/document' require 'net/http' -require 'ftools' +require 'fileutils' +# require 'ftools' require 'kconv' exit if defined?(REQUIRE2LIB) @@ -222,7 +223,7 @@ class Commands interfaces = @commandline.arguments if interfaces.empty? then - interfaces = ['en','cz','de','it','nl','ro','fr'] + interfaces = ['en','cs','de','it','nl','ro','fr'] end interfaces.each do |interface| @@ -305,112 +306,112 @@ class Commands end -class Commands - - include CommandBase - - public - - def translateinterface - - # since we know what kind of file we're dealing with, - # we do it quick and dirty instead of using rexml or - # xslt - - interfaces = @commandline.arguments - - if interfaces.empty? then - interfaces = ['cz','de','it','nl','ro','fr'] - else - interfaces.delete('en') - end - - interfaces.flatten.each do |interface| - - variables, constants, strings, list, data = Hash.new, Hash.new, Hash.new, '', '' - - keyfile, intfile, outfile = "keys-#{interface}.xml", "cont-en.xml", "cont-#{interface}.xml" - - report("generating #{keyfile}") - - begin - one = "texexec --make --all #{interface}" - two = "texexec --batch --silent --interface=#{interface} x-set-01" - if @commandline.option("force") then - system(one) - system(two) - elsif not system(two) then - system(one) - system(two) - end - rescue - end - - unless File.file?(keyfile) then - report("no #{keyfile} generated") - next - end - - report("loading #{keyfile}") - - begin - list = IO.read(keyfile) - rescue - list = empty - end - - if list.empty? then - report("error in loading #{keyfile}") - next - end - - list.i_load('cd:variable', variables) - list.i_load('cd:constant', constants) - list.i_load('cd:command' , strings) - # list.i_load('cd:element' , strings) - - report("loading #{intfile}") - - begin - data = IO.read(intfile) - rescue - data = empty - end - - if data.empty? then - report("error in loading #{intfile}") - next - end - - report("translating interface en to #{interface}") - - data.i_translate('cd:string' , 'value', strings) - data.i_translate('cd:variable' , 'value', variables) - data.i_translate('cd:parameter', 'name' , constants) - data.i_translate('cd:constant' , 'type' , variables) - data.i_translate('cd:variable' , 'type' , variables) - data.i_translate('cd:inherit' , 'name' , strings) - # data.i_translate('cd:command' , 'name' , strings) - - data.gsub!(/(\<cd\:interface[^\>]*?language=")en(")/) do - $1 + interface + $2 - end - - report("saving #{outfile}") - - begin - if f = File.open(outfile, 'w') then - f.write(data) - f.close - end - rescue - end - - end - - end - -end +# class Commands +# +# include CommandBase +# +# public +# +# def translateinterface +# +# # since we know what kind of file we're dealing with, +# # we do it quick and dirty instead of using rexml or +# # xslt +# +# interfaces = @commandline.arguments +# +# if interfaces.empty? then +# interfaces = ['cs','de','it','nl','ro','fr'] +# else +# interfaces.delete('en') +# end +# +# interfaces.flatten.each do |interface| +# +# variables, constants, strings, list, data = Hash.new, Hash.new, Hash.new, '', '' +# +# keyfile, intfile, outfile = "keys-#{interface}.xml", "cont-en.xml", "cont-#{interface}.xml" +# +# report("generating #{keyfile}") +# +# begin +# one = "texexec --make --all #{interface}" +# two = "texexec --batch --silent --interface=#{interface} x-set-01" +# if @commandline.option("force") then +# system(one) +# system(two) +# elsif not system(two) then +# system(one) +# system(two) +# end +# rescue +# end +# +# unless File.file?(keyfile) then +# report("no #{keyfile} generated") +# next +# end +# +# report("loading #{keyfile}") +# +# begin +# list = IO.read(keyfile) +# rescue +# list = empty +# end +# +# if list.empty? then +# report("error in loading #{keyfile}") +# next +# end +# +# list.i_load('cd:variable', variables) +# list.i_load('cd:constant', constants) +# list.i_load('cd:command' , strings) +# # list.i_load('cd:element' , strings) +# +# report("loading #{intfile}") +# +# begin +# data = IO.read(intfile) +# rescue +# data = empty +# end +# +# if data.empty? then +# report("error in loading #{intfile}") +# next +# end +# +# report("translating interface en to #{interface}") +# +# data.i_translate('cd:string' , 'value', strings) +# data.i_translate('cd:variable' , 'value', variables) +# data.i_translate('cd:parameter', 'name' , constants) +# data.i_translate('cd:constant' , 'type' , variables) +# data.i_translate('cd:variable' , 'type' , variables) +# data.i_translate('cd:inherit' , 'name' , strings) +# # data.i_translate('cd:command' , 'name' , strings) +# +# data.gsub!(/(\<cd\:interface[^\>]*?language=")en(")/) do +# $1 + interface + $2 +# end +# +# report("saving #{outfile}") +# +# begin +# if f = File.open(outfile, 'w') then +# f.write(data) +# f.close +# end +# rescue +# end +# +# end +# +# end +# +# end class Commands @@ -542,6 +543,7 @@ class Commands "log", "tmp", "run", "bck", "rlg", "mpt", "mpx", "mpd", "mpo", "mpb", "ctl", + "pgf", "synctex.gz", "tmp.md5", "tmp.out" ] $texonlysuffixes = [ @@ -1219,14 +1221,15 @@ class Language def located(filename) begin - fname = Kpse.found(filename, 'context') - if FileTest.file?(fname) then - report("using file #{fname}") - return fname - else - report("file #{filename} is not present") - return nil + ["context","plain","latex"].each do |name| # fallbacks needed for czech patterns + fname = Kpse.found(filename, name) + if FileTest.file?(fname) then + report("using file #{fname}") + return fname + end end + report("file #{filename} is not present") + return nil rescue report("file #{filename} cannot be located using kpsewhich") return nil @@ -1311,9 +1314,9 @@ class Language remap(/\"o/, "[odiaeresis]") remap(/\"u/, "[udiaeresis]") when 'fr' then - demap(/\\n\{/, "\\keep{") - remap(/\\ae/, "[adiaeresis]") - remap(/\\oe/, "[odiaeresis]") + demap(/\\n\{/, "\\delete{") + remap(/\\ae/, "[aeligature]") + remap(/\\oe/, "[oeligature]") when 'la' then # \lccode`'=`' somewhere else, todo demap(/\\c\{/, "\\delete{") @@ -1324,7 +1327,7 @@ class Language remap("a2|", "[greekalphaiotasub]") remap("h2|", "[greeketaiotasub]") remap("w2|", "[greekomegaiotasub]") - remap(">2r1<2r", "[2ῤ1ῥ]") + remap(">2r1<2r", "[2ῤ1ῥ]") remap(">a2n1wdu'", "[ἀ2ν1ωδύ]") remap(">e3s2ou'", "[ἐ3σ2ού]") # main conversion @@ -1561,6 +1564,8 @@ class Language remap(/\xC0/, "[cyrillicyu]") remap(/\xD1/, "[cyrillicya]") remap(/\xA3/, "[cyrillicyo]") + when 'tr' then + remap(/\^\^11/, "[dotlessi]") else end @@ -1632,7 +1637,7 @@ class Commands @@languagedata['ba' ] = [ 'ec' , ['bahyph.tex'] ] @@languagedata['ca' ] = [ 'ec' , ['cahyph.tex'] ] @@languagedata['cy' ] = [ 'ec' , ['cyhyph.tex'] ] - @@languagedata['cz' ] = [ 'ec' , ['czhyphen.tex','czhyphen.ex'] ] + @@languagedata['cs' ] = [ 'ec' , ['czhyphen.tex','czhyphen.ex'] ] @@languagedata['de' ] = [ 'ec' , ['dehyphn.tex'] ] @@languagedata['deo'] = [ 'ec' , ['dehypht.tex'] ] @@languagedata['da' ] = [ 'ec' , ['dkspecial.tex','dkcommon.tex'] ] @@ -1644,7 +1649,7 @@ class Commands # ghyphen.readme ghyph31.readme grphyph @@languagedata['hr' ] = [ 'ec' , ['hrhyph.tex'] ] @@languagedata['hu' ] = [ 'ec' , ['huhyphn.tex'] ] - @@languagedata['en' ] = [ 'default' , [['ushyphmax.tex'],['ushyph.tex'],['hyphen.tex']] ] + @@languagedata['us' ] = [ 'default' , [['ushyphmax.tex'],['ushyph.tex'],['hyphen.tex']] ] @@languagedata['us' ] = [ 'default' , [['ushyphmax.tex'],['ushyph.tex'],['hyphen.tex']] ] # inhyph.tex @@languagedata['is' ] = [ 'ec' , ['ishyph.tex'] ] @@ -1664,7 +1669,7 @@ class Commands # srhyphc.tex / cyrillic @@languagedata['sv' ] = [ 'ec' , ['svhyph.tex'] ] @@languagedata['tr' ] = [ 'ec' , ['tkhyph.tex'] ] - @@languagedata['uk' ] = [ 'default' , [['ukhyphen.tex'],['ukhyph.tex']] ] + @@languagedata['gb' ] = [ 'default' , [['ukhyphen.tex'],['ukhyph.tex']] ] # @@languagedata['ru' ] = [ 't2a' , ['ruhyphal.tex'] ] # t2a does not work @@languagedata['ru' ] = [ 'cyr' , ['ruhyphal.tex'] ] end @@ -2276,6 +2281,7 @@ class TexDeps report("loading files") report('') n = 0 +# try tex and mkiv @files.each do |filename| if File.file?(filename) and f = File.open(filename) then defs, uses, l = 0, 0, 0 @@ -2739,7 +2745,7 @@ commandline.registeraction('jeditinterface' , 'generate jedit syntax files [- commandline.registeraction('bbeditinterface' , 'generate bbedit syntax files [--pipe]') commandline.registeraction('sciteinterface' , 'generate scite syntax files [--pipe]') commandline.registeraction('rawinterface' , 'generate raw syntax files [--pipe]') -commandline.registeraction('translateinterface', 'generate interface files (xml) [nl de ..]') +# commandline.registeraction('translateinterface', 'generate interface files (xml) [nl de ..]') commandline.registeraction('purgefiles' , 'remove temporary files [--all --recurse] [basename]') commandline.registeraction('documentation' , 'generate documentation [--type=] [filename]') commandline.registeraction('filterpages' ) # no help, hidden temporary feature diff --git a/Master/texmf-dist/scripts/context/ruby/fcd_start.rb b/Master/texmf-dist/scripts/context/ruby/fcd_start.rb index 348ac75ba83..28f407c761e 100644 --- a/Master/texmf-dist/scripts/context/ruby/fcd_start.rb +++ b/Master/texmf-dist/scripts/context/ruby/fcd_start.rb @@ -260,6 +260,7 @@ class FastCD puts(Dir.pwd.gsub(/\\/o, '/')) end rescue + puts("some error") end end @@ -272,6 +273,7 @@ class FastCD else f.puts("cd #{dir.gsub("\\",'/')}") end + f.close end @result = dir report("changing to #{dir}",true) @@ -283,6 +285,7 @@ class FastCD end def choose(args=[]) + offset = 97 unless @pattern.empty? then begin case @result.size @@ -301,7 +304,7 @@ class FastCD return end else - index = answer[0] - ?a + index = answer[0] - offset if dir = list[index] then chdir(dir) return @@ -309,21 +312,27 @@ class FastCD end end rescue + puts("some error") end loop do print("\n") list.each_index do |i| +begin if i < @@maxlength then - puts("#{(i+?a).chr} #{list[i]}") + # puts("#{(i+?a).chr} #{list[i]}") + puts("#{(i+offset).chr} #{list[i]}") else puts("\n there are #{list.length-@@maxlength} entries more") break end +rescue + puts("some error") +end end print("\n>> ") if answer = wait then - if answer >= ?a and answer <= ?z then - index = answer - ?a + if answer >= offset and answer <= offset+25 then + index = answer - offset if dir = list[index] then print("#{answer.chr} ") chdir(dir) @@ -350,7 +359,7 @@ class FastCD end end rescue - # report($!) + report($!) end end end diff --git a/Master/texmf-dist/scripts/context/ruby/graphics/gs.rb b/Master/texmf-dist/scripts/context/ruby/graphics/gs.rb index cb3d016f4cb..6143c881232 100644 --- a/Master/texmf-dist/scripts/context/ruby/graphics/gs.rb +++ b/Master/texmf-dist/scripts/context/ruby/graphics/gs.rb @@ -13,7 +13,8 @@ require 'base/variables' require 'base/system' -require 'ftools' +require 'fileutils' +# Require 'ftools' class GhostScript @@ -218,15 +219,15 @@ class GhostScript rescue report("job aborted due to some error: #{$!}") begin - File.delete(resultfile) if test(?e,resultfile) + File.delete(resultfile) if FileTest.file?(resultfile) rescue report("unable to delete faulty #{resultfile}") end ok = false ensure deleteprofile(getvariable('profile')) - File.delete(@@pstempfile) if test(?e,@@pstempfile) - File.delete(@@pdftempfile) if test(?e,@@pdftempfile) + File.delete(@@pstempfile) if FileTest.file?(@@pstempfile) + File.delete(@@pdftempfile) if FileTest.file?(@@pdftempfile) end return ok end @@ -243,13 +244,14 @@ class GhostScript def pdfmethod? (str) case method(str).to_i - when 3, 4, 5 then return true + when 1, 3, 4, 5 then return true end return false end def pdfprefix (str) case method(str).to_i + when 1 then return 'raw-' when 4 then return 'lowres-' when 5 then return 'normal-' end @@ -383,7 +385,7 @@ class GhostScript debug('piping data') unless pipebounded(tmp,eps) then debug('something went wrong in the pipe') - File.delete(outfile) if test(?e,outfile) + File.delete(outfile) if FileTest.file?(outfile) end debug('closing pipe') eps.close_write @@ -412,7 +414,7 @@ class GhostScript unless ok then begin report('no output file due to error') - File.delete(outfile) if test(?e,outfile) + File.delete(outfile) if FileTest.file?(outfile) rescue # debug("fatal error: #{$!}") debug('file',outfile,'may be invalid') @@ -421,7 +423,7 @@ class GhostScript debug('deleting temp file') begin - File.delete(@@pstempfile) if test(?e,@@pstempfile) + File.delete(@@pstempfile) if FileTest.file?(@@pstempfile) rescue end @@ -467,7 +469,7 @@ class GhostScript # def convertcropped (inpfile, outfile) # report("converting #{inpfile} cropped") # do_convertbounded(inpfile, @@pdftempfile) - # return unless test(?e,@@pdftempfile) + # return unless FileTest.file?(@@pdftempfile) # arguments = " --offset=#{@offset} #{@@pdftempfile} #{outfile}" # report("calling #{@@pdftrimwhite}") # unless ok = System.run(@@pdftrimwhite,arguments) then diff --git a/Master/texmf-dist/scripts/context/ruby/kpseclient.rb b/Master/texmf-dist/scripts/context/ruby/kpseclient.rb deleted file mode 100755 index 547cd9feed8..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/kpseclient.rb +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env ruby - -# require 'profile' - -n, t = 100, Time.now - -$: << File.dirname(File.expand_path($0)) - -require 'base/kpseremote' - -kpse = KpseRemote.new # fast start (.25 sec) -# kpse = KpseRemote::fetch # slow start (1-2 sec) - -# puts kpse.inspect - -exit unless kpse - -if true then - - n = 1 - loop do - str = kpse.find_file('texnansi.enc') - puts("#{n}: #{str}") - n += 1 - sleep(1) - end - -else - - print((Time.now-t).to_s + ' ') - n.times do |i| - str = kpse.find_file('texnansi.enc') - if i == 0 then - print(Time.now-t).to_s + ' ' - print str - else - print ' .' - end - end - puts ' ' + ((Time.now-t)/n).to_s - -end diff --git a/Master/texmf-dist/scripts/context/ruby/kpseserver.rb b/Master/texmf-dist/scripts/context/ruby/kpseserver.rb deleted file mode 100755 index b9fe2d8a6b8..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/kpseserver.rb +++ /dev/null @@ -1,7 +0,0 @@ -#!/usr/bin/env ruby - -$: << File.dirname(File.expand_path($0)) - -require 'base/kpseremote' - -KpseRemote::start_server diff --git a/Master/texmf-dist/scripts/context/ruby/pdftools.rb b/Master/texmf-dist/scripts/context/ruby/pdftools.rb index 23edfeca226..8ad74ec4f36 100644 --- a/Master/texmf-dist/scripts/context/ruby/pdftools.rb +++ b/Master/texmf-dist/scripts/context/ruby/pdftools.rb @@ -20,7 +20,8 @@ $: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.u require 'base/switch' require 'base/logger' -require 'ftools' +require 'fileutils' +# require 'ftools' class File diff --git a/Master/texmf-dist/scripts/context/ruby/rlxtools.rb b/Master/texmf-dist/scripts/context/ruby/rlxtools.rb index 1617fcad4ae..6a5c5ca2098 100644 --- a/Master/texmf-dist/scripts/context/ruby/rlxtools.rb +++ b/Master/texmf-dist/scripts/context/ruby/rlxtools.rb @@ -19,7 +19,8 @@ require 'base/logger' require 'base/system' require 'base/kpse' -require 'ftools' +require 'fileutils' +# require 'ftools' require 'rexml/document' class Commands @@ -111,7 +112,7 @@ class Commands REXML::XPath.each(localsteps,tag) do |extras| REXML::XPath.each(extras,"rl:value") do |value| if name = value.attributes['name'] then - substititute(value,variables[name.to_s] || '') + substitute(value,variables[name.to_s] || '') end end end @@ -144,7 +145,7 @@ class Commands end REXML::XPath.each(command,"rl:value") do |value| if name = value.attributes['name'] then - substititute(value,variables[name.to_s]) + substitute(value,variables[name.to_s]) end end str = justtext(command.to_s) @@ -203,7 +204,7 @@ class Commands return str.strip end - def substititute(value,str='') + def substitute(value,str='') if str then begin if value.attributes.key?('method') then diff --git a/Master/texmf-dist/scripts/context/ruby/rsfiltool.rb b/Master/texmf-dist/scripts/context/ruby/rsfiltool.rb index f3abfdfc703..6d7c7aba0a5 100644 --- a/Master/texmf-dist/scripts/context/ruby/rsfiltool.rb +++ b/Master/texmf-dist/scripts/context/ruby/rsfiltool.rb @@ -18,7 +18,8 @@ end # todo : split session stuff from xmpl/base into an xmpl/session module and "include xmpl/session" into base and here and ... -require 'ftools' +require 'fileutils' +# require 'ftools' require 'xmpl/base' require 'xmpl/switch' require 'xmpl/request' diff --git a/Master/texmf-dist/scripts/context/ruby/rslibtool.rb b/Master/texmf-dist/scripts/context/ruby/rslibtool.rb deleted file mode 100644 index 7ae5efb647e..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/rslibtool.rb +++ /dev/null @@ -1,114 +0,0 @@ -# program : rslibtool -# copyright : PRAGMA Publishing On Demand -# version : 1.00 - 2002 -# author : Hans Hagen -# -# project : eXaMpLe -# concept : Hans Hagen -# info : j.hagen@xs4all.nl -# www : www.pragma-pod.com / www.pragma-ade.com - -# --add --base=filename --path=directory pattern -# --remove --base=filename --path=directory label -# --sort --base=filename --path=directory -# --purge --base=filename --path=directory -# --dummy --base=filename -# --namespace - -# rewrite - -unless defined? ownpath - ownpath = $0.sub(/[\\\/]\w*?\.rb/i,'') - $: << ownpath -end - -require 'rslb/base' -require 'xmpl/base' -require 'xmpl/switch' - -session = Example.new('rslbtool', '1.0', 'PRAGMA POD') - -session.identify - -commandline = CommandLine.new - -commandline.registerflag('add') -commandline.registerflag('remove') -commandline.registerflag('delete') -commandline.registerflag('sort') -commandline.registerflag('purge') -commandline.registerflag('dummy') -commandline.registerflag('process') -commandline.registerflag('namespace') - -commandline.registervalue('prefix') -commandline.registervalue('base') -commandline.registervalue('path') -commandline.registervalue('result') -commandline.registervalue('texexec') -commandline.registervalue('zipalso') - -commandline.expand - -session.inherit(commandline) - -base = session.get('option.base') -path = session.get('option.path') - -base = 'rslbtool.xml' if base.empty? - -# when path is given, assume that arg list is list of -# suffixes, else assume it is a list of globbed filespec - -if path.empty? - base += '.xml' unless base =~ /\..+$/ - list = commandline.arguments -else - Dir.chdir(File.dirname(path)) - list = Dir.glob("*.{#{commandline.arguments.join(',')}}") -end - -begin - reslib = Resource.new(base,session.get('option.namespace')) - reslib.load(base) -rescue - session.error('problems with loading base') - exit -end - -unless session.get('option.texexec').empty? - reslib.set_texexec(session.get('option.texexec')) -end - -if session.get('option.add') - - session.report('adding records', list) - reslib.add_figures(list,session.get('option.prefix')) - -elsif session.get('option.remove') or session.get('option.delete') - - session.report('removing records') - reslib.delete_figures(list) - -elsif session.get('option.sort') - - session.report('sorting records') - reslib.sort_figures() - -elsif session.get('option.purge') - - session.report('purging records') - reslib.purge_figures() - -elsif session.get('option.dummy') - - session.report('creating dummy records') - reslib.create_dummies(session.get('option.process'),session.get('option.result'),session.get('option.zipalso')) - -else - - session.warning('provide action') - -end - -reslib.save(base) diff --git a/Master/texmf-dist/scripts/context/ruby/runtools.rb b/Master/texmf-dist/scripts/context/ruby/runtools.rb index 9c504845ab1..5565748e272 100644 --- a/Master/texmf-dist/scripts/context/ruby/runtools.rb +++ b/Master/texmf-dist/scripts/context/ruby/runtools.rb @@ -1,5 +1,6 @@ require 'timeout' -require 'ftools' +require 'fileutils' +# require 'ftools' require 'rbconfig' class File diff --git a/Master/texmf-dist/scripts/context/ruby/texexec.rb b/Master/texmf-dist/scripts/context/ruby/texexec.rb index a09572c6caa..94b14e4283c 100644 --- a/Master/texmf-dist/scripts/context/ruby/texexec.rb +++ b/Master/texmf-dist/scripts/context/ruby/texexec.rb @@ -1,8 +1,12 @@ -banner = ['TeXExec', 'version 6.2.0', '1997-2006', 'PRAGMA ADE/POD'] +#!/usr/bin/env ruby +#encoding: ASCII-8BIT + +banner = ['TeXExec', 'version 6.2.1', '1997-2009', 'PRAGMA ADE/POD'] $: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! -require 'ftools' # needed ? +require 'fileutils' +# require 'ftools' # needed ? require 'base/switch' require 'base/logger' @@ -277,6 +281,7 @@ class Commands info = `pdfinfo #{filename}` if info =~ /Pages:\s*(\d+)/ then nofpages = $1.to_i + result = @commandline.checkedoption('result','texexec') nofpages.times do |i| if f = File.open(tempfile,"w") then n = i + 1 @@ -285,8 +290,10 @@ class Commands f << "\\externalfigure[#{filename}][object=no,page=#{n}]\n" f << "\\stopTEXpage\\stoptext\n" f.close + job.setvariable('result',"#{result}-#{n}") job.setvariable('interface','english') # redundant job.setvariable('simplerun',true) + job.setvariable('purge',true) job.setvariable('files',[tempfile]) job.processtex end diff --git a/Master/texmf-dist/scripts/context/ruby/texmfstart.rb b/Master/texmf-dist/scripts/context/ruby/texmfstart.rb index e43929213f5..97087c3ae40 100755 --- a/Master/texmf-dist/scripts/context/ruby/texmfstart.rb +++ b/Master/texmf-dist/scripts/context/ruby/texmfstart.rb @@ -1,4 +1,9 @@ #!/usr/bin/env ruby +#encoding: ASCII-8BIT + +# We have removed the fast, server and client variants and no longer +# provide the distributed 'serve trees' option. After all, we're now +# using luatex. # program : texmfstart # copyright : PRAGMA Advanced Document Engineering @@ -18,8 +23,6 @@ # Of couse I can make this into a nice class, which i'll undoubtely will # do when I feel the need. In that case it will be part of a bigger game. -# turning this into a service would be nice, so some day ... - # --locate => provides location # --exec => exec instead of system # --iftouched=a,b => only if timestamp a<>b @@ -34,30 +37,17 @@ $: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! require "rbconfig" -require "md5" +require "fileutils" -# funny, selfmergs was suddenly broken to case problems - -# kpse_merge_done: require 'base/kpseremote' -# kpse_merge_done: require 'base/kpsedirect' -# kpse_merge_done: require 'base/kpsefast' -# kpse_merge_done: require 'base/merge' +require "digest/md5" # kpse_merge_start -# kpse_merge_file: 't:/ruby/base/kpsefast.rb' - -# module : base/kpsefast -# copyright : PRAGMA Advanced Document Engineering -# version : 2005 -# author : Hans Hagen -# -# project : ConTeXt / eXaMpLe -# concept : Hans Hagen -# info : j.hagen@xs4all.nl - -# todo: multiple cnf files -# +class File + def File::makedirs(*x) + FileUtils.makedirs(x) + end +end class String @@ -106,1147 +96,6 @@ class File end -module KpseUtil - - # to be adapted, see loading cnf file - - @@texmftrees = ['texmf-local','texmf.local','../..','texmf'] # '../..' is for gwtex - @@texmfcnf = 'texmf.cnf' - - def KpseUtil::identify - # we mainly need to identify the local tex stuff and wse assume that - # the texmfcnf variable is set; otherwise we need to expand the - # TEXMF variable and that takes time since it may involve more - ownpath = File.expand_path($0) - if ownpath.gsub!(/texmf.*?$/o, '') then - ENV['SELFAUTOPARENT'] = ownpath - else - ENV['SELFAUTOPARENT'] = '.' # fall back - # may be too tricky: - # - # (ENV['PATH'] ||'').split_path.each do |p| - # if p.gsub!(/texmf.*?$/o, '') then - # ENV['SELFAUTOPARENT'] = p - # break - # end - # end - end - filenames = Array.new - if ENV['TEXMFCNF'] && ! ENV['TEXMFCNF'].empty? then - ENV['TEXMFCNF'].to_s.split_path.each do |path| - filenames << File.join(path,@@texmfcnf) - end - elsif ENV['SELFAUTOPARENT'] == '.' then - filenames << File.join('.',@@texmfcnf) - else - @@texmftrees.each do |tree| - filenames << File.join(ENV['SELFAUTOPARENT'],tree,'web2c',@@texmfcnf) - end - end - loop do - busy = false - filenames.collect! do |f| - f.gsub(/\$([a-zA-Z0-9\_\-]+)/o) do - if (! ENV[$1]) || (ENV[$1] == $1) then - "$#{$1}" - else - busy = true - ENV[$1] - end - end - end - break unless busy - end - filenames.delete_if do |f| - ! FileTest.file?(f) - end - return filenames - end - - def KpseUtil::environment - Hash.new.merge(ENV) - end - -end - -class KpseFast - - # formats are an incredible inconsistent mess - - @@suffixes = Hash.new - @@formats = Hash.new - @@suffixmap = Hash.new - - @@texmfcnf = 'texmf.cnf' - - @@suffixes['gf'] = ['.<resolution>gf'] # todo - @@suffixes['pk'] = ['.<resolution>pk'] # todo - @@suffixes['tfm'] = ['.tfm'] - @@suffixes['afm'] = ['.afm'] - @@suffixes['base'] = ['.base'] - @@suffixes['bib'] = ['.bib'] - @@suffixes['bst'] = ['.bst'] - @@suffixes['cnf'] = ['.cnf'] - @@suffixes['ls-R'] = ['ls-R', 'ls-r'] - @@suffixes['fmt'] = ['.fmt', '.efmt', '.efm', '.ofmt', '.ofm', '.oft', '.eofmt', '.eoft', '.eof', '.pfmt', '.pfm', '.epfmt', '.epf', '.xpfmt', '.xpf', '.afmt', '.afm'] - @@suffixes['map'] = ['.map'] - @@suffixes['mem'] = ['.mem'] - @@suffixes['mf'] = ['.mf'] - @@suffixes['mfpool'] = ['.pool'] - @@suffixes['mft'] = ['.mft'] - @@suffixes['mp'] = ['.mp'] - @@suffixes['mppool'] = ['.pool'] - @@suffixes['ocp'] = ['.ocp'] - @@suffixes['ofm'] = ['.ofm', '.tfm'] - @@suffixes['opl'] = ['.opl'] - @@suffixes['otp'] = ['.otp'] - @@suffixes['ovf'] = ['.ovf'] - @@suffixes['ovp'] = ['.ovp'] - @@suffixes['graphic/figure'] = ['.eps', '.epsi'] - @@suffixes['tex'] = ['.tex'] - @@suffixes['texpool'] = ['.pool'] - @@suffixes['PostScript header'] = ['.pro'] - @@suffixes['type1 fonts'] = ['.pfa', '.pfb'] - @@suffixes['vf'] = ['.vf'] - @@suffixes['ist'] = ['.ist'] - @@suffixes['truetype fonts'] = ['.ttf', '.ttc'] - @@suffixes['web'] = ['.web', '.ch'] - @@suffixes['cweb'] = ['.w', '.web', '.ch'] - @@suffixes['enc files'] = ['.enc'] - @@suffixes['cmap files'] = ['.cmap'] - @@suffixes['subfont definition files'] = ['.sfd'] - @@suffixes['lig files'] = ['.lig'] - @@suffixes['bitmap font'] = [] - @@suffixes['MetaPost support'] = [] - @@suffixes['TeX system documentation'] = [] - @@suffixes['TeX system sources'] = [] - @@suffixes['Troff fonts'] = [] - @@suffixes['dvips config'] = [] - @@suffixes['type42 fonts'] = [] - @@suffixes['web2c files'] = [] - @@suffixes['other text files'] = [] - @@suffixes['other binary files'] = [] - @@suffixes['misc fonts'] = [] - @@suffixes['opentype fonts'] = [] - @@suffixes['pdftex config'] = [] - @@suffixes['texmfscripts'] = [] - - # replacements - - @@suffixes['fmt'] = ['.fmt'] - @@suffixes['type1 fonts'] = ['.pfa', '.pfb', '.pfm'] - @@suffixes['tex'] = ['.tex', '.xml'] - @@suffixes['texmfscripts'] = ['rb','lua','py','pl'] - - @@suffixes.keys.each do |k| @@suffixes[k].each do |s| @@suffixmap[s] = k end end - - # TTF2TFMINPUTS - # MISCFONTS - # TEXCONFIG - # DVIPDFMINPUTS - # OTFFONTS - - @@formats['gf'] = '' - @@formats['pk'] = '' - @@formats['tfm'] = 'TFMFONTS' - @@formats['afm'] = 'AFMFONTS' - @@formats['base'] = 'MFBASES' - @@formats['bib'] = '' - @@formats['bst'] = '' - @@formats['cnf'] = '' - @@formats['ls-R'] = '' - @@formats['fmt'] = 'TEXFORMATS' - @@formats['map'] = 'TEXFONTMAPS' - @@formats['mem'] = 'MPMEMS' - @@formats['mf'] = 'MFINPUTS' - @@formats['mfpool'] = 'MFPOOL' - @@formats['mft'] = '' - @@formats['mp'] = 'MPINPUTS' - @@formats['mppool'] = 'MPPOOL' - @@formats['ocp'] = 'OCPINPUTS' - @@formats['ofm'] = 'OFMFONTS' - @@formats['opl'] = 'OPLFONTS' - @@formats['otp'] = 'OTPINPUTS' - @@formats['ovf'] = 'OVFFONTS' - @@formats['ovp'] = 'OVPFONTS' - @@formats['graphic/figure'] = '' - @@formats['tex'] = 'TEXINPUTS' - @@formats['texpool'] = 'TEXPOOL' - @@formats['PostScript header'] = 'TEXPSHEADERS' - @@formats['type1 fonts'] = 'T1FONTS' - @@formats['vf'] = 'VFFONTS' - @@formats['ist'] = '' - @@formats['truetype fonts'] = 'TTFONTS' - @@formats['web'] = '' - @@formats['cweb'] = '' - @@formats['enc files'] = 'ENCFONTS' - @@formats['cmap files'] = 'CMAPFONTS' - @@formats['subfont definition files'] = 'SFDFONTS' - @@formats['lig files'] = 'LIGFONTS' - @@formats['bitmap font'] = '' - @@formats['MetaPost support'] = '' - @@formats['TeX system documentation'] = '' - @@formats['TeX system sources'] = '' - @@formats['Troff fonts'] = '' - @@formats['dvips config'] = '' - @@formats['type42 fonts'] = 'T42FONTS' - @@formats['web2c files'] = 'WEB2C' - @@formats['other text files'] = '' - @@formats['other binary files'] = '' - @@formats['misc fonts'] = '' - @@formats['opentype fonts'] = 'OPENTYPEFONTS' - @@formats['pdftex config'] = 'PDFTEXCONFIG' - @@formats['texmfscripts'] = 'TEXMFSCRIPTS' - - attr_accessor :progname, :engine, :format, :rootpath, :treepath, - :verbose, :remember, :scandisk, :diskcache, :renewcache - - @@cacheversion = '1' - - def initialize - @rootpath = '' - @treepath = '' - @progname = 'kpsewhich' - @engine = 'pdftex' - @variables = Hash.new - @expansions = Hash.new - @files = Hash.new - @found = Hash.new - @kpsevars = Hash.new - @lsrfiles = Array.new - @cnffiles = Array.new - @verbose = true - @remember = true - @scandisk = true - @diskcache = true - @renewcache = false - @isolate = false - - @diskcache = false - @cachepath = nil - @cachefile = 'tmftools.log' - - @environment = ENV - end - - def set(key,value) - case key - when 'progname' then @progname = value - when 'engine' then @engine = value - when 'format' then @format = value - end - end - - def push_environment(env) - @environment = env - end - - # {$SELFAUTOLOC,$SELFAUTODIR,$SELFAUTOPARENT}{,{/share,}/texmf{-local,}/web2c} - # - # $SELFAUTOLOC : /usr/tex/bin/platform - # $SELFAUTODIR : /usr/tex/bin - # $SELFAUTOPARENT : /usr/tex - # - # since we live in scriptpath we need a slightly different method - - def load_cnf(filenames=nil) - unless filenames then - ownpath = File.expand_path($0) - if ownpath.gsub!(/texmf.*?$/o, '') then - @environment['SELFAUTOPARENT'] = ownpath - else - @environment['SELFAUTOPARENT'] = '.' - end - unless @treepath.empty? then - unless @rootpath.empty? then - @treepath = @treepath.split(',').collect do |p| File.join(@rootpath,p) end.join(',') - end - @environment['TEXMF'] = @treepath - # only the first one - @environment['TEXMFCNF'] = File.join(@treepath.split(',').first,'texmf/web2c') - end - unless @rootpath.empty? then - @environment['TEXMFCNF'] = File.join(@rootpath,'texmf/web2c') - @environment['SELFAUTOPARENT'] = @rootpath - @isolate = true - end - filenames = Array.new - if @environment['TEXMFCNF'] and not @environment['TEXMFCNF'].empty? then - @environment['TEXMFCNF'].to_s.split_path.each do |path| - filenames << File.join(path,@@texmfcnf) - end - elsif @environment['SELFAUTOPARENT'] == '.' then - filenames << File.join('.',@@texmfcnf) - else - ['texmf-local','texmf'].each do |tree| - filenames << File.join(@environment['SELFAUTOPARENT'],tree,'web2c',@@texmfcnf) - end - end - end - # <root>/texmf/web2c/texmf.cnf - filenames = _expanded_path_(filenames) - @rootpath = filenames.first - 3.times do - @rootpath = File.dirname(@rootpath) - end - filenames.collect! do |f| - f.gsub("\\", '/') - end - filenames.each do |fname| - if FileTest.file?(fname) and f = File.open(fname) then - @cnffiles << fname - while line = f.gets do - loop do - # concatenate lines ending with \ - break unless line.sub!(/\\\s*$/o) do - f.gets || '' - end - end - case line - when /^[\%\#]/o then - # comment - when /^\s*(.*?)\s*\=\s*(.*?)\s*$/o then - key, value = $1, $2 - unless @variables.key?(key) then - value.sub!(/\%.*$/,'') - value.sub!(/\~/, "$HOME") - @variables[key] = value - end - @kpsevars[key] = true - end - end - f.close - end - end - end - - def load_lsr - @lsrfiles = [] - simplified_list(expansion('TEXMF')).each do |p| - ['ls-R','ls-r'].each do |f| - filename = File.join(p,f) - if FileTest.file?(filename) then - @lsrfiles << [filename,File.size(filename)] - break - end - end - end - @files = Hash.new - if @diskcache then - ['HOME','TEMP','TMP','TMPDIR'].each do |key| - if @environment[key] then - if FileTest.directory?(@environment[key]) then - @cachepath = @environment[key] - @cachefile = [@rootpath.gsub(/[^A-Z0-9]/io, '-').gsub(/\-+/,'-'),File.basename(@cachefile)].join('-') - break - end - end - end - if @cachepath and not @renewcache and FileTest.file?(File.join(@cachepath,@cachefile)) then - begin - if f = File.open(File.join(@cachepath,@cachefile)) then - cacheversion = Marshal.load(f) - if cacheversion == @@cacheversion then - lsrfiles = Marshal.load(f) - if lsrfiles == @lsrfiles then - @files = Marshal.load(f) - end - end - f.close - end - rescue - @files = Hash.new - end - end - end - return if @files.size > 0 - @lsrfiles.each do |filedata| - filename, filesize = filedata - filepath = File.dirname(filename) - begin - path = '.' - data = IO.readlines(filename) - if data[0].chomp =~ /% ls\-R \-\- filename database for kpathsea\; do not change this line\./io then - data.each do |line| - case line - when /^[a-zA-Z0-9]/o then - line.chomp! - if @files[line] then - @files[line] << path - else - @files[line] = [path] - end - when /^\.\/(.*?)\:$/o then - path = File.join(filepath,$1) - end - end - end - rescue - # sorry - end - end - if @diskcache and @cachepath and f = File.open(File.join(@cachepath,@cachefile),'wb') then - f << Marshal.dump(@@cacheversion) - f << Marshal.dump(@lsrfiles) - f << Marshal.dump(@files) - f.close - end - end - - def expand_variables - @expansions = Hash.new - if @isolate then - @variables['TEXMFCNF'] = @environment['TEXMFCNF'].dup - @variables['SELFAUTOPARENT'] = @environment['SELFAUTOPARENT'].dup - else - @environment.keys.each do |e| - if e =~ /^([a-zA-Z]+)\_(.*)\s*$/o then - @expansions["#{$1}.#{$2}"] = (@environment[e] ||'').dup - else - @expansions[e] = (@environment[e] ||'').dup - end - end - end - @variables.keys.each do |k| - @expansions[k] = @variables[k].dup unless @expansions[k] - end - loop do - busy = false - @expansions.keys.each do |k| - @expansions[k].gsub!(/\$([a-zA-Z0-9\_\-]*)/o) do - busy = true - @expansions[$1] || '' - end - @expansions[k].gsub!(/\$\{([a-zA-Z0-9\_\-]*)\}/o) do - busy = true - @expansions[$1] || '' - end - end - break unless busy - end - @expansions.keys.each do |k| - @expansions[k] = @expansions[k].gsub("\\", '/') - end - end - - def variable(name='') - (name and not name.empty? and @variables[name.sub('$','')]) or '' - end - - def expansion(name='') - (name and not name.empty? and @expansions[name.sub('$','')]) or '' - end - - def variable?(name='') - name and not name.empty? and @variables.key?(name.sub('$','')) - end - - def expansion?(name='') - name and not name.empty? and @expansions.key?(name.sub('$','')) - end - - def simplified_list(str) - lst = str.gsub(/^\{/o,'').gsub(/\}$/o,'').split(",") - lst.collect do |l| - l.sub(/^[\!]*/,'').sub(/[\/\\]*$/o,'') - end - end - - def original_variable(variable) - if variable?("#{@progname}.#{variable}") then - variable("#{@progname}.#{variable}") - elsif variable?(variable) then - variable(variable) - else - '' - end - end - - def expanded_variable(variable) - if expansion?("#{variable}.#{@progname}") then - expansion("#{variable}.#{@progname}") - elsif expansion?(variable) then - expansion(variable) - else - '' - end - end - - def original_path(filename='') - _expanded_path_(original_variable(var_of_format_or_suffix(filename)).split(";")) - end - - def expanded_path(filename='') - _expanded_path_(expanded_variable(var_of_format_or_suffix(filename)).split(";")) - end - - def _expanded_path_(pathlist) - i, n = 0, 0 - pathlist.collect! do |mainpath| - mainpath.gsub(/([\{\}])/o) do - if $1 == "{" then - i += 1 ; n = i if i > n ; "<#{i}>" - else - i -= 1 ; "</#{i+1}>" - end - end - end - n.times do |i| - loop do - more = false - newlist = [] - pathlist.each do |path| - unless path.sub!(/^(.*?)<(#{n-i})>(.*?)<\/\2>(.*?)$/) do - pre, mid, post = $1, $3, $4 - mid.gsub!(/\,$/,',.') - mid.split(',').each do |m| - more = true - if m == '.' then - newlist << "#{pre}#{post}" - else - newlist << "#{pre}#{m}#{post}" - end - end - end then - newlist << path - end - end - if more then - pathlist = [newlist].flatten # copy -) - else - break - end - end - end - pathlist = pathlist.uniq.collect do |path| - p = path - # p.gsub(/^\/+/o) do '' end - # p.gsub!(/(.)\/\/(.)/o) do "#{$1}/#{$2}" end - # p.gsub!(/\/\/+$/o) do '//' end - p.gsub!(/\/\/+/o) do '//' end - p - end - pathlist - end - - # todo: ignore case - - def var_of_format(str) - @@formats[str] || '' - end - - def var_of_suffix(str) # includes . - if @@suffixmap.key?(str) then @@formats[@@suffixmap[str]] else '' end - end - - def var_of_format_or_suffix(str) - if @@formats.key?(str) then - @@formats[str] - elsif @@suffixmap.key?(File.extname(str)) then # extname includes . - @@formats[@@suffixmap[File.extname(str)]] # extname includes . - else - '' - end - end - -end - -class KpseFast - - # test things - - def list_variables(kpseonly=true) - @variables.keys.sort.each do |k| - if kpseonly then - puts("#{k} = #{@variables[k]}") if @kpsevars[k] - else - puts("#{if @kpsevars[k] then 'K' else 'E' end} #{k} = #{@variables[k]}") - end - end - end - - def list_expansions(kpseonly=true) - @expansions.keys.sort.each do |k| - if kpseonly then - puts("#{k} = #{@expansions[k]}") if @kpsevars[k] - else - puts("#{if @kpsevars[k] then 'K' else 'E' end} #{k} = #{@expansions[k]}") - end - end - end - - def list_lsr - puts("files = #{@files.size}") - end - - def set_test_patterns - @variables["KPSE_TEST_PATTERN_A"] = "foo/{1,2}/bar//" - @variables["KPSE_TEST_PATTERN_B"] = "!!x{A,B{1,2}}y" - @variables["KPSE_TEST_PATTERN_C"] = "x{A,B//{1,2}}y" - @variables["KPSE_TEST_PATTERN_D"] = "x{A,B//{1,2,}}//y" - end - - def show_test_patterns - ['A','B','D'].each do |i| - puts "" - puts @variables ["KPSE_TEST_PATTERN_#{i}"] - puts "" - puts expand_path("KPSE_TEST_PATTERN_#{i}").split_path - puts "" - end - end - -end - -class KpseFast - - # kpse stuff - - def expand_braces(str) # output variable and brace expansion of STRING. - _expanded_path_(original_variable(str).split_path).join_path - end - - def expand_path(str) # output complete path expansion of STRING. - _expanded_path_(expanded_variable(str).split_path).join_path - end - - def expand_var(str) # output variable expansion of STRING. - expanded_variable(str) - end - - def show_path(str) # output search path for file type NAME - expanded_path(str).join_path - end - - def var_value(str) # output the value of variable $STRING. - original_variable(str) - end - -end - -class KpseFast - - def _is_cnf_?(filename) - filename == File.basename((@cnffiles.first rescue @@texmfcnf) || @@texmfcnf) - end - - def find_file(filename) - if _is_cnf_?(filename) then - @cnffiles.first rescue '' - else - [find_files(filename,true)].flatten.first || '' - end - end - - def find_files(filename,first=false) - if _is_cnf_?(filename) then - result = @cnffiles.dup - else - if @remember then - # stamp = "#{filename}--#{@format}--#{@engine}--#{@progname}" - stamp = "#{filename}--#{@engine}--#{@progname}" - return @found[stamp] if @found.key?(stamp) - end - pathlist = expanded_path(filename) - result = [] - filelist = if @files.key?(filename) then @files[filename].uniq else nil end - done = false - if pathlist.size == 0 then - if FileTest.file?(filename) then - done = true - result << '.' - end - else - pathlist.each do |path| - doscan = if path =~ /^\!\!/o then false else true end - recurse = if path =~ /\/\/$/o then true else false end - pathname = path.dup - pathname.gsub!(/^\!+/o, '') - done = false - if not done and filelist then - # checking for exact match - if filelist.include?(pathname) then - result << pathname - done = true - end - if not done and recurse then - # checking for fuzzy // - pathname.gsub!(/\/+$/o, '/.*') - # pathname.gsub!(/\/\//o,'/[\/]*/') - pathname.gsub!(/\/\//o,'/.*?/') - re = /^#{pathname}/ - filelist.each do |f| - if re =~ f then - result << f # duplicates will be filtered later - done = true - end - break if done - end - end - end - if not done and doscan then - # checking for path itself - pname = pathname.sub(/\.\*$/,'') - if not pname =~ /\*/o and FileTest.file?(File.join(pname,filename)) then - result << pname - done = true - end - end - break if done and first - end - end - if not done and @scandisk then - pathlist.each do |path| - pathname = path.dup - unless pathname.gsub!(/^\!+/o, '') then # !! prevents scan - recurse = pathname.gsub!(/\/+$/o, '') - complex = pathname.gsub!(/\/\//o,'/*/') - if recurse then - if complex then - if ok = File.glob_file("#{pathname}/**/#{filename}") then - result << File.dirname(ok) - done = true - end - elsif ok = File.locate_file(pathname,filename) then - result << File.dirname(ok) - done = true - end - elsif complex then - if ok = File.glob_file("#{pathname}/#{filename}") then - result << File.dirname(ok) - done = true - end - elsif FileTest.file?(File.join(pathname,filename)) then - result << pathname - done = true - end - break if done and first - end - end - end - result = result.uniq.collect do |pathname| - File.join(pathname,filename) - end - @found[stamp] = result if @remember - end - return result # redundant - end - -end - -class KpseFast - - class FileData - attr_accessor :tag, :name, :size, :date - def initialize(tag=0,name=nil,size=nil,date=nil) - @tag, @name, @size, @date = tag, name, size, date - end - def FileData.sizes(a) - a.collect do |aa| - aa.size - end - end - def report - case @tag - when 1 then "deleted | #{@size.to_s.rjust(8)} | #{@date.strftime('%m/%d/%Y %I:%M')} | #{@name}" - when 2 then "present | #{@size.to_s.rjust(8)} | #{@date.strftime('%m/%d/%Y %I:%M')} | #{@name}" - when 3 then "obsolete | #{' '*8} | #{' '*16} | #{@name}" - end - end - end - - def analyze_files(filter='',strict=false,sort='',delete=false) - puts("command line = #{ARGV.join(' ')}") - puts("number of files = #{@files.size}") - puts("filter pattern = #{filter}") - puts("loaded cnf files = #{@cnffiles.join(' ')}") - puts('') - if filter.gsub!(/^not:/,'') then - def the_same(filter,filename) - not filter or filter.empty? or /#{filter}/ !~ filename - end - else - def the_same(filter,filename) - not filter or filter.empty? or /#{filter}/ =~ filename - end - end - @files.keys.each do |name| - if @files[name].size > 1 then - data = Array.new - @files[name].each do |path| - filename = File.join(path,name) - # if not filter or filter.empty? or /#{filter}/ =~ filename then - if the_same(filter,filename) then - if FileTest.file?(filename) then - if delete then - data << FileData.new(1,filename,File.size(filename),File.mtime(filename)) - begin - File.delete(filename) if delete - rescue - end - else - data << FileData.new(2,filename,File.size(filename),File.mtime(filename)) - end - else - # data << FileData.new(3,filename) - end - end - end - if data.length > 1 then - if strict then - # if data.collect do |d| d.size end.uniq! then - # data.sort! do |a,b| b.size <=> a.size end - # data.each do |d| puts d.report end - # puts '' - # end - data.sort! do |a,b| - if a.size and b.size then - b.size <=> a.size - else - 0 - end - end - bunch = Array.new - done = false - data.each do |d| - if bunch.size == 0 then - bunch << d - elsif bunch[0].size == d.size then - bunch << d - else - if bunch.size > 1 then - bunch.each do |b| - puts b.report - end - done = true - end - bunch = [d] - end - end - puts '' if done - else - case sort - when 'size' then data.sort! do |a,b| a.size <=> b.size end - when 'revsize' then data.sort! do |a,b| b.size <=> a.size end - when 'date' then data.sort! do |a,b| a.date <=> b.date end - when 'revdate' then data.sort! do |a,b| b.date <=> a.date end - end - data.each do |d| puts d.report end - puts '' - end - end - end - end - end - -end - - - # k = KpseFast.new # (root) - # k.set_test_patterns - # k.load_cnf - # k.expand_variables - # k.load_lsr - - # k.show_test_patterns - - # puts k.list_variables - # puts k.list_expansions - # k.list_lsr - # puts k.expansion("$TEXMF") - # puts k.expanded_path("TEXINPUTS","context") - - # k.progname, k.engine, k.format = 'context', 'pdftex', 'tfm' - # k.scandisk = false # == must_exist - # k.expand_variables - - # 10.times do |i| puts k.find_file('texnansi-lmr10.tfm') end - - # puts "expand braces $TEXMF" - # puts k.expand_braces("$TEXMF") - # puts "expand path $TEXMF" - # puts k.expand_path("$TEXMF") - # puts "expand var $TEXMF" - # puts k.expand_var("$TEXMF") - # puts "expand path $TEXMF" - # puts k.show_path('tfm') - # puts "expand value $TEXINPUTS" - # puts k.var_value("$TEXINPUTS") - # puts "expand value $TEXINPUTS.context" - # puts k.var_value("$TEXINPUTS.context") - - # exit - - - -# kpse_merge_file: 't:/ruby/base/kpse/trees.rb' - -require 'monitor' -# kpse_merge_done: require 'base/kpsefast' - -class KpseTrees < Monitor - - def initialize - @trees = Hash.new - end - - def pattern(filenames) - filenames.join('|').gsub(/\\+/o,'/').downcase - end - - def choose(filenames,environment) - current = pattern(filenames) - load(filenames,environment) unless @trees[current] - puts "enabling tree #{current}" - current - end - - def fetch(filenames,environment) # will send whole object ! - current = pattern(filenames) - load(filenames,environment) unless @trees[current] - puts "fetching tree #{current}" - @trees[current] - end - - def load(filenames,environment) - current = pattern(filenames) - puts "loading tree #{current}" - @trees[current] = KpseFast.new - @trees[current].push_environment(environment) - @trees[current].load_cnf(filenames) - @trees[current].expand_variables - @trees[current].load_lsr - end - - def set(tree,key,value) - case key - when 'progname' then @trees[tree].progname = value - when 'engine' then @trees[tree].engine = value - when 'format' then @trees[tree].format = value - end - end - def get(tree,key) - case key - when 'progname' then @trees[tree].progname - when 'engine' then @trees[tree].engine - when 'format' then @trees[tree].format - end - end - - def load_cnf(tree) - @trees[tree].load_cnf - end - def load_lsr(tree) - @trees[tree].load_lsr - end - def expand_variables(tree) - @trees[tree].expand_variables - end - def expand_braces(tree,str) - @trees[tree].expand_braces(str) - end - def expand_path(tree,str) - @trees[tree].expand_path(str) - end - def expand_var(tree,str) - @trees[tree].expand_var(str) - end - def show_path(tree,str) - @trees[tree].show_path(str) - end - def var_value(tree,str) - @trees[tree].var_value(str) - end - def find_file(tree,filename) - @trees[tree].find_file(filename) - end - def find_files(tree,filename,first) - @trees[tree].find_files(filename,first) - end - -end - - -# kpse_merge_file: 't:/ruby/base/kpse/drb.rb' - -require 'drb' -# kpse_merge_done: require 'base/kpse/trees' - -class KpseServer - - attr_accessor :port - - def initialize(port=7000) - @port = port - end - - def start - puts "starting drb service at port #{@port}" - DRb.start_service("druby://localhost:#{@port}", KpseTrees.new) - trap(:INT) do - DRb.stop_service - end - DRb.thread.join - end - - def stop - # todo - end - -end - -class KpseClient - - attr_accessor :port - - def initialize(port=7000) - @port = port - @kpse = nil - end - - def start - # only needed when callbacks are used / slow, due to Socket::getaddrinfo - # DRb.start_service - end - - def object - @kpse = DRbObject.new(nil,"druby://localhost:#{@port}") - end - -end - - -# SERVER_URI="druby://localhost:8787" -# -# # Start a local DRbServer to handle callbacks. -# # -# # Not necessary for this small example, but will be required -# # as soon as we pass a non-marshallable object as an argument -# # to a dRuby call. -# DRb.start_service -# - - -# kpse_merge_file: 't:/ruby/base/kpseremote.rb' - -# kpse_merge_done: require 'base/kpsefast' - -case ENV['KPSEMETHOD'] - when /soap/o then # kpse_merge_done: require 'base/kpse/soap' - when /drb/o then # kpse_merge_done: require 'base/kpse/drb' - else # kpse_merge_done: require 'base/kpse/drb' -end - -class KpseRemote - - @@port = ENV['KPSEPORT'] || 7000 - @@method = ENV['KPSEMETHOD'] || 'drb' - - def KpseRemote::available? - @@method && @@port - end - - def KpseRemote::start_server(port=nil) - kpse = KpseServer.new(port || @@port) - kpse.start - end - - def KpseRemote::start_client(port=nil) # keeps object in server - kpseclient = KpseClient.new(port || @@port) - kpseclient.start - kpse = kpseclient.object - tree = kpse.choose(KpseUtil::identify, KpseUtil::environment) - [kpse, tree] - end - - def KpseRemote::fetch(port=nil) # no need for defining methods but slower, send whole object - kpseclient = KpseClient.new(port || @@port) - kpseclient.start - kpseclient.object.fetch(KpseUtil::identify, KpseUtil::environment) rescue nil - end - - def initialize(port=nil) - if KpseRemote::available? then - begin - @kpse, @tree = KpseRemote::start_client(port) - rescue - @kpse, @tree = nil, nil - end - else - @kpse, @tree = nil, nil - end - end - - def progname=(value) - @kpse.set(@tree,'progname',value) - end - def format=(value) - @kpse.set(@tree,'format',value) - end - def engine=(value) - @kpse.set(@tree,'engine',value) - end - - def progname - @kpse.get(@tree,'progname') - end - def format - @kpse.get(@tree,'format') - end - def engine - @kpse.get(@tree,'engine') - end - - def load - @kpse.load(KpseUtil::identify, KpseUtil::environment) - end - def okay? - @kpse && @tree - end - def set(key,value) - @kpse.set(@tree,key,value) - end - def load_cnf - @kpse.load_cnf(@tree) - end - def load_lsr - @kpse.load_lsr(@tree) - end - def expand_variables - @kpse.expand_variables(@tree) - end - def expand_braces(str) - clean_name(@kpse.expand_braces(@tree,str)) - end - def expand_path(str) - clean_name(@kpse.expand_path(@tree,str)) - end - def expand_var(str) - clean_name(@kpse.expand_var(@tree,str)) - end - def show_path(str) - clean_name(@kpse.show_path(@tree,str)) - end - def var_value(str) - clean_name(@kpse.var_value(@tree,str)) - end - def find_file(filename) - clean_name(@kpse.find_file(@tree,filename)) - end - def find_files(filename,first=false) - # dodo: each filename - @kpse.find_files(@tree,filename,first) - end - - private - - def clean_name(str) - str.gsub(/\\/,'/') - end - -end - - # kpse_merge_file: 't:/ruby/base/kpsedirect.rb' class KpseDirect @@ -1284,14 +133,11 @@ class KpseDirect end - # kpse_merge_stop - - $mswindows = Config::CONFIG['host_os'] =~ /mswin/ $separator = File::PATH_SEPARATOR -$version = "2.0.3" +$version = "2.1.0" $ownpath = File.dirname($0) if $mswindows then @@ -1335,7 +181,7 @@ $predefined['ctxtools'] = 'ctxtools.rb' $predefined['rlxtools'] = 'rlxtools.rb' $predefined['pdftools'] = 'pdftools.rb' $predefined['mpstools'] = 'mpstools.rb' -$predefined['exatools'] = 'exatools.rb' +# $predefined['exatools'] = 'exatools.rb' $predefined['xmltools'] = 'xmltools.rb' # $predefined['luatools'] = 'luatools.lua' # $predefined['mtxtools'] = 'mtxtools.rb' @@ -1412,22 +258,7 @@ def check_kpse if $kpse then # already done else - begin - if KpseRemote::available? then - $kpse = KpseRemote.new - if $kpse.okay? then - puts("kpse : remote") if $verbose - else - $kpse = KpseDirect.new - puts("kpse : direct (forced)") if $verbose - end - else - $kpse = KpseDirect.new - puts("kpse : direct") if $verbose - end - rescue - puts("kpse : direct (fallback)") if $verbose - end + $kpse = KpseDirect.new end end @@ -1488,18 +319,6 @@ end class File - # def File.needsupdate(oldname,newname) - # begin - # if $mswindows then - # return File.stat(oldname).mtime > File.stat(newname).mtime - # else - # return File.stat(oldname).mtime != File.stat(newname).mtime - # end - # rescue - # return true - # end - # end - @@update_eps = 1 def File.needsupdate(oldname,newname) @@ -1543,33 +362,6 @@ class File end -# def hashed (arr=[]) - # arg = if arr.class == String then arr.split(' ') else arr.dup end - # hsh = Hash.new - # if arg.length > 0 - # hsh['arguments'] = '' - # done = false - # arg.each do |s| - # if done then - # if s =~ / / then - # hsh['arguments'] += " \"#{s}\"" # maybe split on = - # else - # hsh['arguments'] += " #{s}" - # end - # else - # kvl = s.split('=') - # if kvl[0].sub!(/^\-+/,'') then - # hsh[kvl[0]] = if kvl.length > 1 then kvl[1] else true end - # else - # hsh['file'] = s - # done = true - # end - # end - # end - # end - # return hsh -# end - def hashed (arr=[]) arg = if arr.class == String then arr.split(' ') else arr.dup end hsh = Hash.new @@ -2129,7 +921,7 @@ def make(filename,windows=false,linux=false,remove=false) return elsif not remove then if windows then - ['bat','exe'].each do |suffix| + ['bat','cmd','exe'].each do |suffix| if FileTest.file?("#{basename}.#{suffix}") then report("windows stub '#{basename}.#{suffix}' skipped (already present)") return @@ -2197,7 +989,7 @@ def process(&block) checkname = filename + ".md5" oldchecksum, newchecksum = "old", "new" begin - newchecksum = MD5.new(IO.read(filename)).hexdigest.upcase + newchecksum = Digest::MD5.hexdigest(IO.read(filename)).upcase rescue newchecksum = "new" else @@ -2417,22 +1209,6 @@ def execute(arguments) # br global elsif $selfcleanup then output("ruby libraries are cleaned up") if SelfMerge::cleanup return true - elsif $serve then - if ENV['KPSEMETHOD'] && ENV['KPSEPORT'] then - # # kpse_merge_done: require 'base/kpseremote' - begin - KpseRemote::start_server - rescue - return false - else - return true - end - else - usage - puts("") - puts("message : set 'KPSEMETHOD' and 'KPSEPORT' variables") - return false - end elsif $help || ! $filename || $filename.empty? then usage loadtree($tree) diff --git a/Master/texmf-dist/scripts/context/ruby/textools.rb b/Master/texmf-dist/scripts/context/ruby/textools.rb index 442dc19240e..a5858c5caf5 100644 --- a/Master/texmf-dist/scripts/context/ruby/textools.rb +++ b/Master/texmf-dist/scripts/context/ruby/textools.rb @@ -20,7 +20,8 @@ $: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.u require 'base/switch' require 'base/logger' -require 'ftools' +require 'fileutils' +# require 'ftools' # Remark # diff --git a/Master/texmf-dist/scripts/context/ruby/www/admin.rb b/Master/texmf-dist/scripts/context/ruby/www/admin.rb deleted file mode 100644 index 8983ca2b77c..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/www/admin.rb +++ /dev/null @@ -1,215 +0,0 @@ -require 'fileutils' - -require 'www/lib' -require 'www/dir' -require 'www/common' - -class WWW - - include Common - - # klopt nog niet, twee keer task met een verschillend doel - - def handle_exatask - # case @session.check('task', request_variable('task')) - task, options, option = @session.get('task'), @session.get('option').split(@@re_bar), request_variable('option') - option = (options.first || '') if option.empty? - case task - when 'exaadmin' - @session.set('status', 'admin') # admin: status|dir - touch_session(@session.get('id')) - if options.include?(option) then - case option - when 'status' then handle_exaadmin_status - when 'dir' then handle_exaadmin_dir - else handle_exaadmin_status - end - elsif option.empty? then - message('Status', "unknown option") - else - message('Status', "option '#{option}' not permitted #{options.inspect}") - end - else - message('Status', "unknown task '#{task}'") - end - end - - def handle_exaadmin - if id = valid_session() then - handle_exatask - else - message('Status', 'no login') - end - end - - def handle_exaadmin_dir - check_template_file('exalogin','exalogin-template.htm') - @interface.set('path:docroot', work_root) - @interface.set('dir:uri', 'exaadmin') # forces the dir handler into cgi mode - @interface.set('dir:task', 'exaadmin') # forces the dir handler into cgi mode - @interface.set('dir:option', 'dir') # forces the dir handler into cgi mode - filename = "#{@@session_prefix}#{request_variable('path')}" - fullname = File.join(work_root,filename) - if request_variable('path').empty? then - handle_exaadmin_status - elsif FileTest.directory?(fullname) then - handle_dir(filename, [], false) - elsif File.zero?(fullname) then - message('Error', "The file '#{filename}' is empty") - elsif File.size?(fullname) > (4 * 1024 * 1024) then - if FileTest.file?(File.expand_path(File.join(cache_root,filename))) then - str = "<br/><br/>Cached alternative: <a href=\"#{File.join('cache',filename)}\">#{File.basename(filename)}</a>" - else - str = '' - end - message('Error', "The file '#{filename}' is too big to serve over cgi." + str) - else - send_file(fullname) - end - end - - def handle_exaadmin_status - check_template_file('exalogin','exalogin-template.htm') - begin - n, str, lines, list, start, most, least, cached = 0, '', '', Hash.new, Time.now, 0, 0, false - filename = File.join(tmp_path(dirname),'sessions.rbd') - begin - File.open(filename) do |f| - list = Marshal.load(f) - end - rescue - cached, list = false, Hash.new - else - cached = true - end - files = Dir.glob("{#{work_roots.join(',')}}/#{@@session_prefix}*.ses") - list.keys.each do |l| - list.delete(l) unless files.include?(l) # slow - end - files.each do |f| - ctime = File.ctime(f) - stime = list[f][0] == ctime rescue 0 - unless ctime == stime then - begin - hash = load_session_file(f) - rescue - else - list[f] = [ctime,hash] - end - end - end - begin - File.open(filename,'w') do |f| - f << Marshal.dump(list) - end - rescue - # no save - end - begin - keys = list.keys.sort do |a,b| - case list[b][0] <=> list[a][0] - when -1 then -1 - when +1 then +1 - else - a <=> b - end - end - rescue - keys = list.keys.sort - end - totaltime, totaldone = 0.0, 0 - if keys.length > 0 then - keys.each do |entry| - s, t, session = entry, list[entry][0], list[entry][1] - status = session['status'] || '' - runtime = (session['runtime'] || '').to_f rescue 0 - starttime = (start.to_i-session['starttime'].to_i).to_s rescue '' - requesttime = session['endtime'].to_i-session['starttime'].to_i rescue 0 - requesttime = if requesttime > 0 then requesttime.to_s else '' end - if runtime > 0.0 then - totaltime += runtime - totaldone += 1 - if least > 0 then - if runtime < least then least = runtime end - else - least = runtime - end - if most > 0 then - if runtime > most then most = runtime end - else - most = runtime - end - end - if status.empty? then - # skip, garbage - elsif status =~ /^(|exa)admin/o then - # skip, useless - else - begin - lines << "<tr>\n" - lines << td("<a href=\"exaadmin?option=dir&path=#{session['id']}.dir\">#{session['id']}</a>") - lines << td(status) - lines << td(session['timeout']) - lines << td(starttime) - lines << td(session['runtime']) - lines << td(requesttime) - lines << td(t.strftime("%H:%M:%S %Y-%m-%d")) - lines << td(session['domain']) - lines << td(session['project']) - lines << td(session['username']) - lines << td(File.basename(File.dirname(s))) - lines << "</tr>\n" - rescue - else - n += 1 - end - end - end - if n > 0 then - str = "<table cellpadding='0'>\n" - str << "<tr>\n" - str << th('session identifier') - str << th('status') - str << th('timeout') - str << th('time') - str << th('runtime') - str << th('total') - str << th('modification time') - str << th('domain') - str << th('project') - str << th('username') - str << th('process') - str << "</tr>\n" - str << lines - str << "</table>\n" - end - end - rescue - message('Status', "#{$!} There is currently no status available.", false, @@admin_refresh, 'exaadmin') - else - if n > 0 then - # r = if n > 100 then 60 else @@admin_refresh.to_i end # scanning takes long - r = @@admin_refresh - average = "average = #{if totaldone > 0 then sprintf('%.02f',totaltime/totaldone) else '0' end} (#{sprintf('%.02f',least)} .. #{sprintf('%.02f',most)})" - sessions = "sessions = #{n}" - refresh = "refresh = #{r.to_s} sec" - loadtime = "loadtime = #{sprintf('%.04f',Time.now-start)} sec" - cached = if cached then "cached" else "not cached" end - message("Status | #{sessions} | #{refresh} | #{loadtime} - #{cached} | #{average} |", str, false, r, 'exaadmin') - else - message('Status', "There are no sessions registered.", false, @@admin_refresh, 'exaadmin') - end - end - end - - private - - def th(str) - "<th align='left'>#{str} </th>\n" - end - - def td(str) - "<td><code>#{str || ''}  </code></td>\n" - end - -end diff --git a/Master/texmf-dist/scripts/context/ruby/www/common.rb b/Master/texmf-dist/scripts/context/ruby/www/common.rb deleted file mode 100644 index 9c383229456..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/www/common.rb +++ /dev/null @@ -1,80 +0,0 @@ -# We cannot chdir in threads because it is something -# process wide, so we will run into problems with the -# other threads. The same is true for the global ENV -# pseudo hash, so we cannot communicate the runpath -# via an anvironment either. This leaves texmfstart -# in combination with a path directive and an tmf file. - -module Common # can be a mixin - - # we assume that the hash.subset method is defined - - @@re_texmfstart = /^(texmfstart|ruby\s*texmfstart.rb)\s*(.*)$/ - @@re_texmfpath = /^\-\-path\=/ - - def command_string(path,command,log='') - runner = "texmfstart --path=#{File.expand_path(path)}" - if command =~ @@re_texmfstart then - cmd, arg = $1, $2 - if arg =~ @@re_texmfpath then - # there is already an --path (first switch) - else - command = "#{runner} #{arg}" - end - else - command = "#{runner} bin:#{command}" - end - if log && ! log.empty? then - return "#{command} 2>&1 > #{File.expand_path(File.join(path,log))}" - else - return command - end - end - - def set_os_vars - begin - ENV['TEXOS'] = ENV['TEXOS'] || platform - rescue - ENV['TEXOS'] = 'texmf-linux' - else - ENV['TEXOS'] = 'texmf-' + ENV['TEXOS'] unless ENV['TEXOS'] =~ /^texmf\-/ - ensure - ENV['EXA:TEXOS'] = ENV['TEXOS'] - end - end - - def set_environment(hash) - set_os_vars - paths = ENV['PATH'].split(File::PATH_SEPARATOR) - hash.subset('binpath:').keys.each do |key| - begin - paths << File.expand_path(hash[key]) - rescue - end - end - ENV['PATH'] = paths.uniq.join(File::PATH_SEPARATOR) - hash.subset('path:').keys.each do |path| - key, value = "EXA:#{path.upcase}", File.expand_path(hash[path]) - ENV[key] = value - end - end - - def save_environment(hash,path,filename='request.tmf') - begin - File.open(File.join(path,filename),'w') do |f| - set_os_vars - ['EXA:TEXOS','TEXOS'].each do |key| - f.puts("#{key} = #{ENV[key]}") - end - hash.subset('binpath:').keys.each do |key| - f.puts("PATH < #{File.expand_path(@interface.get(key))}") - end - hash.subset('path:').keys.each do |path| - f.puts("EXA:#{path.upcase} = #{File.expand_path(@interface.get(path))}") - end - end - rescue - end - end - -end diff --git a/Master/texmf-dist/scripts/context/ruby/www/dir.rb b/Master/texmf-dist/scripts/context/ruby/www/dir.rb deleted file mode 100644 index 115fd8911d9..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/www/dir.rb +++ /dev/null @@ -1,155 +0,0 @@ -require 'www/lib' - -# dir handling - -class WWW - - # borrowed code from webrick demo, patched - - @@dir_name_width = 25 - - def handle_dir(dirpath=@variables.get('path'),hidden=[],showdirs=true) - check_template_file('dir','text-template.htm') - docroot = @interface.get('path:docroot') - dirpath = dirpath || '' - hidden = [] unless hidden - local_path = dirpath.dup - title, str = "Index of #{escaped(dirpath)}", '' - begin - local_path.gsub!(/[\/\\]+/,'/') - local_path.gsub!(/\/$/, '') - if local_path !~ /^(\.|\.\.|\/|[a-zA-Z]\:)$/io then # maybe also /... - full_path = File.join(docroot,local_path) - @interface.set('log:dir', full_path) - begin - list = Dir::entries(full_path) - rescue - str << "unable to parse #{local_path}" - else - if list then - list.collect! do |name| - if name =~ /^\.+/o then - nil # no . and .. - else - st = (File::stat(File.join(docroot,local_path,name)) rescue nil) - if st.nil? then - [name, nil, -1, false] - elsif st.directory? then - if showdirs then [name + "/", st.mtime, -1, true] else nil end - elsif hidden.length > 0 then - if hidden.include?(name) then nil else [name, st.mtime, st.size, false] end - else - [name, st.mtime, st.size, false] - end - end - end - list.compact! - n, m, s = @variables.get('n'), @variables.get('m'), @variables.get('s') - if ! n.empty? then - idx, d0 = 0, n - elsif ! m.empty? then - idx, d0 = 1, m - elsif ! s.empty? then - idx, d0 = 2, s - else - idx, d0 = 0, 'a' - end - d1 = if d0 == 'a' then 'd' else 'a' end - if d0 == 'a' then - list.sort! do |a,b| a[idx] <=> b[idx] end - else - list.sort! do |a,b| b[idx] <=> a[idx] end - end - u = dir_uri(@variables.get('path') || '.') - str << "<div class='dir-view'>\n<pre>\n" - str << "<a href=\"#{u}&n=#{d1}\">name</a>".ljust(49+u.length) - str << "<a href=\"#{u}&m=#{d1}\">last modified</a>".ljust(41+u.length) - str << "<a href=\"#{u}&s=#{d1}\">size</a>".rjust(31+u.length) << "\n" << "\n" - # parent path - if showdirs && ! hidden.include?('..') then - dname = "parent directory" - fname = "#{File.dirname(dirpath)}" - time = File::mtime(File.join(docroot,local_path,"/..")) - str << dir_entry(fname,dname,time,-1,true) - str << "\n" - end - # directories - done = false - list.each do |name, time, size, dir| - if dir then - if name.size > @@dir_name_width then - dname = name.sub(/^(.#{@@dir_name_width-2})(.*)/) do $1 + ".." end - else - dname = name - end - fname = "#{escaped(dirpath)}/#{escaped(name)}" - str << dir_entry(fname,dname,time,size,dir) - done = true - end - end - str << "\n" if done - # files - list.each do |name, time, size, dir| - unless dir then - if name.size > @@dir_name_width then - dname = name.sub(/^(.#{@@dir_name_width-2})(.*)/) do $1 + ".." end - else - dname = name - end - fname = "#{escaped(dirpath)}/#{escaped(name)}" - str << dir_entry(fname,dname,time,size,dir) - end - end - str << "\n" - str << '</pre></div>' - else - str << 'no info' - end - end - else - str << 'no access' - end - rescue - str << "error #{$!}<br/><pre>" - str << $@.join("\n") - str << "</pre>" - end - message(title,str) - end - def dir_uri(f='.') - u, t, o = @interface.get('dir:uri'), @interface.get('dir:task'), @interface.get('dir:option') # takes precedence, in case we run under cgi control - if u.empty? then - u, t, o = @interface.get('process:uri'), '', '' - elsif ! t.empty? then - t = "task=#{t}&" - o = "option=#{o}&" - end - if u && ! u.empty? then - u = u.sub(/\?.*$/,'') # frozen string - if f =~ /^\.+$/ then - "#{u}?#{t}#{o}path=" - else - "#{u}?#{t}#{o}path=#{f}" - end - else - '' - end - end - - def dir_entry(fname,dname,time,size,dir=false) - if dir then - f = fname.sub(/\/+$/,'').sub(/^\/+/,'') - s = "<a href=\"#{dir_uri(f)}\">#{dname}</a>" - elsif ! @interface.get('dir:uri').empty? then # takes precedence, in case we run under cgi control - s = "<a href=\"#{dir_uri(fname.gsub(/\/+/,'/'))}\">#{dname}</a>" - else - s = "<a href=\"#{fname.gsub(/\/+/,'/')}\">#{dname}</a>" - end - # s << " " * (30 - dname.size) - s << " " * (@@dir_name_width + 5 - dname.size) - s << (time ? time.strftime("%Y/%m/%d %H:%M ") : " " * 22) - s << (size >= 0 ? size.to_s : "-").rjust(12) << "\n" - return s - end - -end diff --git a/Master/texmf-dist/scripts/context/ruby/www/exa.rb b/Master/texmf-dist/scripts/context/ruby/www/exa.rb deleted file mode 100644 index 20a40fc7b66..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/www/exa.rb +++ /dev/null @@ -1,387 +0,0 @@ -require 'fileutils' -require 'www/lib' -require 'www/dir' -require 'www/common' -require 'www/admin' - -class WWW - - include Common - - def handle_exadefault - check_template_file('exalogin','exalogin-template.htm') - if id = logged_in_session(true) then - finish_login - else - message('Error', 'No default login permitted.') - end - end - - def handle_exalogin - check_template_file('exalogin','exalogin-template.htm') - if id = logged_in_session(false) then - finish_login - else - message('Error', 'No default login permitted.') - end - end - - def finish_login - get_gui() - filename, path, task = @session.get('gui'), @session.checked('path','.'), @session.get('task') - if ! task.empty? then - save_session - handle_exatask - elsif filename and not filename.empty? then - save_session - fullname = filename.gsub(/\.\./,'') - fullname = File.join(path,filename) unless FileTest.file?(fullname) - fullname = File.join(@interface.get('path:interfaces'), filename) unless FileTest.file?(fullname) - fullname = File.join(@interface.get('path:interfaces'), path, filename) unless FileTest.file?(fullname) - if FileTest.file?(fullname) then - send_file(fullname,true) - else - message('Interface', 'Invalid interface request, no valid interface file.' ) - end - else - message('Interface', 'Invalid interface request, no default interface file.') - end - end - - def handle_exainterface() - check_template_file('text','exalogin-template.htm') - if id = valid_session() then - filename = @interface.get('process:uri').to_s # kind of dup - if ! filename.empty? && filename.sub!(/^.*\//,'') then - path = @session.checked('path', '.') - fullname = filename.gsub(/\.\./,'') - fullname = File.join(path,filename) unless FileTest.file?(fullname) - fullname = File.join(@interface.get('path:interfaces'),filename) unless FileTest.file?(fullname) - fullname = File.join(@interface.get('path:interfaces'),path,filename) unless FileTest.file?(fullname) - if FileTest.file?(fullname) then - save_session - send_file(fullname,true) - else - get_file(filename) - filename, path = @session.get('gui'), @session.checked('path','.') - if filename and not filename.empty? then - save_session - fullname = filename.gsub(/\.\./,'') - fullname = File.join(path,filename) unless FileTest.file?(fullname) - fullname = File.join(@interface.get('path:interfaces'),filename) unless FileTest.file?(fullname) - fullname = File.join(@interface.get('path:interfaces'),path,filename) unless FileTest.file?(fullname) - send_file(fullname,true) if FileTest.file?(fullname) - else - message('Interface', 'Invalid interface request, no interface file.') - end - end - else - message('Interface', 'Invalid interface request, no resource file.') - end - else - message('Interface', 'Invalid interface request, no login.') - end - end - - def handle_exarequest() # todo: check if request is 'command' - check_template_file('exalogin','exalogin-template.htm') - if id = client_session() then - client = true - @interface.set('log:kind', "remote client request: #{id}") - elsif id = valid_session() then - client = false - @interface.set('log:kind', "remote browser request: #{id}") - else - client, id = false, nil - @interface.set('log:kind', 'unknown kind of request') - end - if id then - dir, tmp = dirname, tmp_path(dirname) - requestname, replyname = 'request.exa', 'reply.exa' - requestfile, replyfile = File.join(tmp,requestname), File.join(tmp,replyname) - lockfile = File.join(dirname,lckname) - action, filename, command, url, req = '', '', '', '', '' - extract_sent_files(tmp) - @variables.each do |key, value| - case key - when 'exa:request' then - req = value.dup - when 'exa:action' then - action = value.dup - # when 'exa:command' then - # command = value.dup - # when 'exa:url' then - # url = value.dup - when 'exa:filename' then - filename = value.dup - when 'exa:threshold' then - @interface.set('process:threshold', value.dup) - when /^fakename/o then - @variables.set(key, File.basename(value)) - when /^filename\-/o then - @variables.set(key, filename = File.basename(value)) - when /^dataname\-/o then - @variables.set(key) - else # remove varname- prefix from value - @variables.set(key, @variables.get(key).sub(/#{key}\-/,'')) - end - end - @variables.check('exa:filename', filename) - @variables.check('exa:action', action) - if @variables.empty?('exa:filename') then - @variables.set('exa:filename', @interface.get('log:attachments').split('|').first || '') - end - req.gsub!(/<exa:data\s*\/>/i, '') - dat = "<exa:data>\n" - @variables.each do |key, value| - if ['password','exa:request'].include?(key) then - # skip - elsif ! value || value.empty? then - dat << "<exa:variable label='#{key}'/>\n" - else # todo: escape 'm - dat << "<exa:variable label='#{key}'>#{value}</exa:variable>\n" - end - end - dat << "</exa:data>\n" - if req.empty? then - req << "<?xml version='1.0' ?>\n" - req << "<exa:request xmlns:exa='#{@@namespace}'>\n" - req << "<exa:application>\n" - req << "<exa:action>'#{action}</exa:action>\n" unless action.empty? - # req << "<exa:command>'#{command}</exa:command>\n" unless command.empty? - # req << "<exa:url>'#{url}</exa:url>\n" unless url.empty? - req << "</exa:application>\n" - req << "<exa:comment>constructed request</exa:comment>\n" - req << dat - req << "</exa:request>\n" - else - # better use rexml but slower - if req =~ /<exa:request[^>]*>.*?\s*<exa:threshold>\s*(.*?)\s*<\/exa:threshold>\s*.*?<\/exa:request>/moi then - threshold = $1 - unless threshold.empty? then - @interface.set('process:threshold', threshold) - @session.set('threshold', threshold) - end - end - req.sub!(/(<exa:request[^>]*>.*?)\s*<exa:option>\s*\-\-action\=(.*?)\s*<\/exa:option>\s*(.*?<\/exa:request>)/moi) do - pre, act, pos = $1, $2, $3 - action = act.sub(/\.exa$/,'') if action.empty? - str = "#{pre}<exa:action>#{action}</exa:action>#{pos}" - str.sub(/\s*<exa:command>.*?<\/exa:command>\s*/moi ,'') - end - req.sub!(/(<exa:request[^>]*>.*?)<exa:action>\s*(.*?)\s*<\/exa:action>(.*?<\/exa:request>)/moi) do - pre, act, pos = $1, $2, $3 - action = act.sub(/\.exa$/,'') if action.empty? - str = "#{pre}<exa:action>#{action}</exa:action>#{pos}" - str.sub(/\s*<exa:command>.*?<\/exa:command>\s*/moi ,'') - end - unless req =~ /<exa:data>(.*?)<\/exa:data>/moi then - req.sub!(/(<\/exa:request>)/) do dat + $1 end - end - end - req.sub!(/<exa:filename>.*?<\/exa:filename>/moi, '') - unless @variables.empty?('exa:filename') then - req.sub!(/(<\/exa:application>)/moi) do - "<exa:filename>#{@variables.get('exa:filename')}<\/exa:filename>" + $1 - end - end - @variables.set('exa:action', action) - @interface.set("log:#{requestname}", req) - begin - File.open(requestfile,'w') do |f| - f << req - end - rescue - message('Error', 'There is a problem in handling this request (working path access).') - return - end - File.delete(replyfile) rescue false - @interface.set('log:action',action) - get_command(action) - logdata = '' - begin - command = @session.get('command') - @interface.set('log:command',if command.empty? then '[no command]' else command end) - if ! command.empty? then - @session.set('starttime', Time.now.to_i.to_s) # can be variables and in save list - if @interface.true?('process:background') then - # background - @session.set('status', 'running: background') - @session.set('maxtime', @interface.get('process:timeout')) - @session.set('threshold', @interface.get('process:threshold')) - save_session - timeout(@@watch_delay) do - save_environment(@interface,tmp) - begin - starttime = File.mtime(@session_file) - # crap - loop do - sleep(1) - if starttime != File.mtime(@session_file) then - break unless FileTest.file?(lockfile) - end - end - rescue TimeoutError - if client then - send_reply() - else - message('Status', 'Processing your request takes a while',true,5,'exastatus') - end - return - rescue - end - end - if client then send_reply() else send_result() end - else - # foreground - status = 'running: foreground' - @session.set('status', status) - @session.set('maxtime', @interface.get('process:timeout')) - @session.set('threshold', @interface.get('process:threshold')) - save_session - timeout(@interface.get('process:timeout').to_i) do - begin - status = 'running: foreground' - set_environment(@interface) - save_environment(@interface,tmp) - command = command_string(tmp,command) - logdata = `#{command}` - rescue TimeoutError - status = 'running: timeout' - logdata = "timeout: #{@interface.get('process:timeout')} seconds" - rescue - status = 'running: aborted' - logdata = 'fatal runtime error' - else - @session.set('endtime', Time.now.to_i.to_s) - status = 'running: finished' - end - end - @session.set('status', status) - save_session - case @session.get('status') - when 'running: finished' then - if client then send_reply(logdata) else send_result(logdata) end - when 'running: timeout' then - message('Error', 'There is a problem in handling this request (timeout).') - when 'running: aborted' then - message('Error', 'There is a problem in handling this request (aborted).') - else - message('Error', 'There is a problem in handling this request (unknown).') - end - end - else - message('Error', 'There is a problem in handling this request (no runner).') - end - rescue - message('Error', 'There is a problem in handling this request (no run).' + $!) - end - else - message('Error', 'Invalid session.') - end - end - - def handle_exacommand() # shares code with exarequest - check_template_file('exalogin','exalogin-template.htm') - if id = client_session() then - client = true - @interface.set('log:kind', "remote client request: #{id}") - elsif id = valid_session() then - client = false - @interface.set('log:kind', "remote browser request: #{id}") - else - client, id = false, nil - @interface.set('log:kind', 'unknown kind of request') - end - if id then - dir, tmp = dirname, tmp_path(dirname) - requestname, replyname = 'request.exa', 'reply.exa' - requestfile, replyfile = File.join(tmp,requestname), File.join(tmp,replyname) - req, command, url = '', '', '' - @variables.each do |key, value| - case key - when 'exa:request' then - req = value.dup - when 'exa:command' then - command = value.dup - when 'exa:threshold' then - @interface.set('process:threshold', value.dup) - when 'exa:url' then - url = value.dup - end - end - unless req.empty? then - # better use rexml but slower / reuse these : command = filter_from_request('exa:command') - if req =~ /<exa:request[^>]*>.*?\s*<exa:command>\s*(.*?)\s*<\/exa:command>\s*.*?<\/exa:request>/moi then - command = $1 - end - if req =~ /<exa:request[^>]*>.*?\s*<exa:url>\s*(.*?)\s*<\/exa:url>\s*.*?<\/exa:request>/moi then - url = $1 - end - if req =~ /<exa:request[^>]*>.*?\s*<exa:threshold>\s*(.*?)\s*<\/exa:threshold>\s*.*?<\/exa:request>/moi then - threshold = $1 - unless threshold.empty? then - @interface.set('process:threshold', threshold) - @session.set('threshold', threshold) - end - end - end - @variables.check('exa:command', command) - @variables.check('exa:url', url) - File.delete(replyfile) rescue false - case @variables.get('exa:command') - when 'fetch' then - if @variables.empty?('exa:url') then - message('Error', "Problems with fetching, no file given") - else - # the action starts here - filename = @variables.get('exa:url').to_s # kind of dup - unless filename.empty? then - get_path(filename) # also registers filename as url - path = @session.checked('path', '') - fullname = filename.gsub(/\.\./,'') - fullname = File.join(path,fullname) unless path.empty? - if FileTest.file?(fullname) then - if client then - send_url(fullname) - else - send_file(fullname,true) - end - @session.set('threshold', @interface.get('process:threshold')) - @session.set('url',filename) - save_session - else - message('Error', "Problems with fetching, unknown file #{fullname}.") - # message('Error', "Problems with fetching, unknown file #{filename}.") - end - else - message('Error', "Problems with fetching, invalid file #{filename}.") - end - # and ends here - end - else - message('Error', "Invalid command #{command}.") - end - else - message('Error', 'Invalid session.') - end - end - - def handle_exastatus - get_cfg() # weird, needed for apache, but not for wwwserver - if request_variable('id').empty? then - if id = valid_session() then - send_result() - else - message('Error', 'Invalid session.') - end - else - if id = valid_session() then - send_reply() - else - send_reply('invalid session') - end - end - end - -end diff --git a/Master/texmf-dist/scripts/context/ruby/www/lib.rb b/Master/texmf-dist/scripts/context/ruby/www/lib.rb deleted file mode 100644 index b9a44c9f61c..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/www/lib.rb +++ /dev/null @@ -1,1405 +0,0 @@ -#!/usr/bin/env ruby - -# This is just a simple environment for remote processing of context -# files. It's not a framework, nor an example of how that should be done. -# Nowadays there are environments like Rails or Nitro. Maybe some day I'll -# give one of them a try. - -# <META Http-Equiv="Cache-Control" Content="no-cache"> -# <META Http-Equiv="Pragma" Content="no-cache"> -# <META Http-Equiv="Expires" Content="0"> - -# we make limited use of cgi methods because we also need to handle webrick - -# %var% as well as $(var) are supported - -# paths need to be expanded before they enter apache, since .. is not -# handled by default - -require 'base/variables' - -require 'ftools' -require 'fileutils' -require 'tempfile' -require 'timeout' -require 'md5' -require 'digest/md5' -require 'cgi' # we also need escaping for webrick (could move it here) - -# beware, namespaces have to match ! - -module XML - - def XML::element(tag,attributes=nil) - if attributes.class == Hash then - if block_given? then - XML::element(tag,XML::attributes(attributes)) do yield end - else - XML::element(tag,XML::attributes(attributes)) - end - else - if block_given? then - "<#{tag}#{if attributes && ! attributes.empty? then ' ' + attributes end}>#{yield}</#{tag}>" - else - "<#{tag}#{if attributes && ! attributes.empty? then ' ' + attributes end}/>" - end - end - end - - def XML::attributes(hash) - str = '' - hash.each do |k,v| - str << ' ' unless str.empty? - if v =~ /\'/ then - str << "#{k}=\"#{v}\"" - else - str << "#{k}=\'#{v}\'" - end - end - return str - end - - def XML::create(version='1.0') - "<?version='#{version}'?>#{yield || ''}" - end - - def XML::line - "\n" - end - -end - -# str = - # XML::create do - # XML::element('test') do - # XML::element('test') do - # 'text a' - # end + - # XML::element('test',XML::attributes({'a'=>'b'})) do - # XML::element('nested',XML::attributes({'a'=>'b'})) do - # 'text b-1' - # end + - # XML::element('nested',XML::attributes({'a'=>'b'})) do - # 'text b-2' - # end - # end + - # XML::element('nested',{'a'=>'b'}) do - # 'text c' - # end - # end - # end - -class ExtendedHash - - DEFAULT = 'default' - - @@re_default = /^(default|)$/i - - def default?(key) - self[key] =~ @@re_default rescue true # unset, empty or 'default' - end - - def default(key) - self[key] = DEFAULT - end - - def match?(key,value) - value == '*' || value == self[key] - end - - -end - -class WWW - - @@session_prefix = '' - @@data_file = 'example.cfg' - @@session_max_age = 60*60 - @@watch_delay = 30 - @@send_threshold = 2*1024*1024 - @@admin_refresh = 10 - @@namespace = "http://www.pragma-ade.com/schemas/example.rng" - - @@re_bar = /\s*\|\s*/ - @@re_lst = /\s*\,\s*/ - @@re_var_a = /\%(.*?)\%/ - @@re_var_b = /\$\((.*?)\)/ - - attr_reader :variables - attr_writer :variables - - @@paths = [ - 'configurations', - 'data', - 'distributions', - 'documents', - 'interfaces', - 'logs', - 'resources', - 'runners', - 'scripts', - 'templates', - 'work'] - - @@re_true = /^\s*(YES|ON|TRUE|1)\s*$/io - @@re_false = /^\s*(NO|OFF|FALSE|0)\s*$/io - - def initialize(webrick_daemon=nil,webrick_request=nil,webrick_response=nil) - @session_id, @session_file = '', '' - @cgi, @cgi_cookie = nil, nil - @webrick_daemon, @webrick_request, @webrick_response = webrick_daemon, webrick_request, webrick_response - - @interface = ExtendedHash.new - @variables = ExtendedHash.new - @session = ExtendedHash.new - - @checked = false - - analyze_request() - update_interface() - - @interface.set('template:message' , 'exalogin-template.htm') - @interface.set('template:status' , 'exalogin-template.htm') - @interface.set('template:login' , 'exalogin.htm') - @interface.set('process:timeout' , @@session_max_age) - @interface.set('process:threshold' , @@send_threshold) - @interface.set('process:background', 'yes') # this demands a watchdog being active - @interface.set('process:indirect' , 'no') # indirect download, no direct feed - @interface.set('process:autologin' , 'yes') # provide default interface when applicable - @interface.set('process:exaurl' , '') # this one will be used as replacement in templates - @interface.set('trace:run' , 'no') - @interface.set('trace:errors' , 'no') - @interface.set('process:os' , platform) - @interface.set('process:texos' , 'texmf-' + platform) - - @interface.set('trace:run' , 'yes') if (ENV['EXA_TRACE_RUN'] || '') =~ @@re_true - @interface.set('trace:errors' , 'yes') if (ENV['EXA_TRACE_ERRORS'] || '') =~ @@re_true - - yield self if block_given? - end - - def set(key,value) - @interface.set(key,value) - end - def get(key) - @interface.get(key,value) - end - - def platform - case RUBY_PLATFORM - when /(mswin|bccwin|mingw|cygwin)/i then 'mswin' - when /(linux)/i then 'linux' - when /(netbsd|unix)/i then 'unix' - when /(darwin|rhapsody|nextstep)/i then 'macosx' - else 'unix' - end - end - - def check_cgi - # when mod_ruby is used, we need to close - # the cgi session explicitly - unless @webrick_request then - unless @cgi then - @cgi = CGI.new('html4') - at_exit do - begin - @cgi.close - rescue - end - end - end - end - end - - def request_variable(key) - begin - if @webrick_request then - [@webrick_request.query[key]].flatten.first.to_s - else - check_cgi - [@cgi.params[key]].flatten.first.to_s - end - rescue - '' - end - end - - def request_cookie(key) - begin - if @cgi then - if str = @cgi.cookies[key] then - return str.first || '' - end - elsif @webrick_request then - @webrick_request.cookies.flatten.each do |cookie| - if cookie.name == key then - return cookie.value unless cookie.value.empty? - end - end - end - rescue - end - return '' - end - - def analyze_request - if @webrick_request then - @interface.set('path:docroot', @webrick_daemon.config[:DocumentRoot] || './documents') - @interface.set('process:uri', @webrick_request.request_uri.to_s) - # @interface.set('process.url', [@webrick_request.host,@webrick_request.request_port].join(':')) - @cgi = nil - @webrick_request.query.each do |key, value| - # todo: filename - @variables.set(key, [value].flatten.first) - end - else - @interface.set('path:docroot', ENV['DOCUMENT_ROOT'] || './documents') - @interface.set('process:uri', ENV['REQUEST_URI'] || '') - # @interface.set('process.url', [ENV['SERVER_NAME'],ENV['SERVER:PORT']].join(':')) - ARGV[0] = '' # get rid of terminal mode - check_cgi - # quite fragile, due to changes between 1.6 and 1.8 - @cgi.params.keys.each do |p| - if @cgi[p].respond_to?(:original_filename) then - @interface.set('log:method','post') - if @cgi[p].original_filename && ! @cgi[p].original_filename.empty? then - @variables.set(p, File.basename(@cgi[p].original_filename)) - else - case @cgi.params[p].class - when StringIO.class then @variables.set(p, @cgi[p].read) - when Array.class then @variables.set(p, @cgi[p].first.to_s) - when String.class then @variables.set(p, @cgi[p]) - when Tempfile.class then @variables.set(p, '[data blob]') - end - end - else - @interface.set('log:method','get') unless @interface.get('log:method') == 'post' - @variables.set(p, [@cgi.params[p]].flatten.first.to_s) - end - end - end - @interface.set('path:root', File.dirname(@interface.get('path:docroot'))) - end - - # name in calling script takes precedence - # one can set template:whatever as well - # todo: in config - - def check_template_file(tag='',filename='exalogin-template.htm') - @interface.set('file:template', filename) if @interface.get('file:template').empty? - @interface.set('tag:template', tag) - @interface.set('file:template', @interface.get('tag:template')) unless @interface.get('tag:template').empty? - end - - def update_interface() - root = @interface.get('path:docroot') - @interface.set('path:docroot', File.expand_path("#{root}")) - @@paths.each do |path| - @interface.set("path:#{path}", File.expand_path("#{root}/../#{path}")) - end - @interface.set('file:template', @interface.get('tag:template')) unless @interface.get('tag:template').empty? - end - - def indirect?(result) - size = FileTest.size?(result) || 0 - @interface.true?('trace:errors') || @interface.true?('trace:run') || @interface.true?('process:indirect') || - ((! @interface.empty?('process:threshold')) && (size > @interface.get('process:threshold').to_i)) || - ((! @session.empty?('threshold')) && (size > @session.get('threshold').to_i)) - end - -end - -# files - -class WWW - - def sesname - File.basename(@session_file) - end - def dirname - File.basename(@session_file.sub(/ses$/,'dir')) - end - def lckname - File.basename(@session_file.sub(/ses$/,'lck')) - end - - def work_root(expand=true) - p = if expand then File.expand_path(@interface.get('path:work')) else @interface.get('path:work') end - if @interface.true?('process:background') then - File.join(@interface.get('path:work'),'watch') - else - File.join(@interface.get('path:work'),'direct') - end - end - - def work_roots(expand=true) - p = if expand then File.expand_path(@interface.get('path:work')) else @interface.get('path:work') end - [File.join(@interface.get('path:work'),'watch'),File.join(@interface.get('path:work'),'direct')] - end - - def cache_root(expand=true) - p = if expand then File.expand_path(@interface.get('path:work')) else @interface.get('path:work') end - File.join(@interface.get('path:work'),'cache') - end - - def cleanup_path(dir) - FileUtils::rm_r(pth) rescue false - end - - def tmp_path(dir) - @interface.set('path:templates', File.expand_path(@interface.get('path:templates'))) # to be sure; here ? ? ? - pth = File.join(work_root,dir) - File.makedirs(pth) rescue false - pth - end - - def locked?(lck) - FileTest.file?(lck) - end - -end - -# sessions - -class WWW - - @@session_tags = ['id','domain','project','username','password','gui','path','process','command','filename','action','status', 'starttime','endtime','runtime','task','option','threshold','url'].sort - @@session_keep = ['id','domain','project','username','password','process'].sort - @@session_reset = @@session_tags - @@session_keep - - def new_session() - if @variables.empty?('exa:session') then - @session_id = new_session_id - else - @session_id = @variables.get('exa:session') - end - if @session_id == 'default' then # ??? - @session_id = new_session_id - end - @session_file = File.join(work_root,"#{@@session_prefix}#{@session_id}.ses") - register_session - return @session_id - end - - def reset_session(all=false) - (if all then @@session_tags else @@session_reset end).each do |k| - @session.set(k) - end - end - - def valid_session - @session_id = request_variable('id') - if @session_id.empty? then - begin - if @cgi then - if @session_id = @cgi.cookies['session_id'] then - @session_id = @session_id.first || '' - else - @session_id = '' - end - elsif @webrick_request then - @webrick_request.cookies.flatten.each do |cookie| - if cookie.name == 'session_id' then - unless cookie.value.empty? then - @session_id = cookie.value - # break - end - end - end - else - @session_id = '' - end - rescue - @interface.set('log:session',"[error in request #{$!}]") - return false - end - end - if @session_id.empty? then - @interface.set('log:session','[no id, check work dir permissions]') - return false - else - @interface.set('log:session',@session_id) - load_session - if ! @session.empty?('domain') && ! @session.empty?('project') && ! @session.empty?('username') then - register_session - return @session_id - else - return false - end - end - end - - def touch_session(id=nil) - begin - t = Time.now - File.utime(t,t,File.join(work_root,"#{@@session_prefix}#{id || @session_id}.ses")) rescue false - rescue - false - end - end - - def forced_session - @session_id = new_session - if @session_id.empty? then - @interface.set('log:session','[no id, check work dir permissions]') - return false - else - return check_session - end - end - - def client_session - request, done = @variables.get('exa:request'), false - request.sub!(/(^.*<exa:request[^>]*>.*?)\s*<exa:client>\s*(.*)\s*<\/exa:client>\s*(.*?<\/exa:request>.*$)/mio) do - pre, client, post = $1, $2, $3 - client.scan(/<exa:(domain|project|username|password)>(.*?)<\/exa:\1>/mio) do - @variables.set($1, $2) - end - done = true - pre + post - end - if done then - return forced_session - else - return nil - end - end - - def register_session - if @cgi then - @cgi_cookie = CGI::Cookie::new( - 'name' => 'session_id', - 'value' => @session_id, - 'expires' => Time.now + @interface.get('process:timeout').to_i - ) - # @cgi_cookie = CGI::Cookie::new('session_id',@session_id) - elsif @webrick_response then - if cookie = WEBrick::Cookie.new('session_id', @session_id) then - cookie.expires = Time.now + @interface.get('process:timeout').to_i - cookie.max_age = @interface.get('process:timeout').to_i - cookie.comment = 'exa identifier' - @webrick_response.cookies.clear - @webrick_response.cookies << cookie - end - end - end - - def new_session_id # taken from cgi - md5 = Digest::MD5::new - now = Time::now - md5.update(now.to_s) - md5.update(String(now.usec)) - md5.update(String(rand(0))) - md5.update(String($$)) - md5.update('foobar') - @new_session = true - md5.hexdigest[0,32] # was 16 - end - - @@hide_passwords = true - HIDDEN = 'hidden' - - def same_passwords(password) # password in cfg file - if @@hide_passwords && (@session.get('password') == HIDDEN) && (@session_id == @session.get('id')) then - # this condition is only true when a same session id is found and - # the password is checked once and set to HIDDEN - same = true - elsif password =~ /^MD5:/ then - # so, one cannot send a known encrypted password since it will be - # encrypted twice then - same = (password == "MD5:" + MD5.new(@session.get('password')).hexdigest.upcase) - else - if (@session.default?('domain') && @session.default?('project') && @session.default?('username')) then - @session.default('password') # is this safe enough? - end - same = (password == @session.get('password')) - end - if @@hide_passwords && same then - @session.set('password', HIDDEN) - save_session # next time this session is ok anyway - end - return same - end - - @@session_line = /^\s*(?![\#\%])(.*?)\s*\=\s*(.*?)\s*$/o - @@session_begin = 'begin exa session' - @@session_end = 'end exa session' - - def loaded_session_data(filename) - begin - if data = IO.readlines(filename) then - return data if (data.first =~ /^[\#\%]\s*#{@@session_begin}/o) && (data.last =~ /^[\#\%]\s*#{@@session_end}/o) - end - rescue - end - return nil - end - - def load_session() - begin - @session_file = File.join(work_root,"#{@@session_prefix}#{@session_id}.ses") - if data = loaded_session_data(@session_file) then - data.each do |line| - if line =~ @@session_line then - @session.set($1, $2 || '') - end - end - else - return false - end - rescue - return false - else - return true - end - end - - def load_session_file(filename) - begin - if data = loaded_session_data(filename) then - session = Hash.new - data.each do |line| - if line =~ @@session_line then - session[$1] = $2 || '' - end - end - else - Hash.new - end - rescue - Hash.new - else - session - end - end - - def save_session - begin - unless @session_id.empty? then - @session_file = File.join(work_root,"#{@@session_prefix}#{@session_id}.ses") - @session_file = File.join(work_root,"#{@@session_prefix}#{@session_id}.ses") - File.open(@session_file,'w') do |f| - f << "\# #{@@session_begin}\n" - @@session_tags.each do |tag| - if @session && @session.key?(tag) then - if ! @session.get(tag).empty? then # no one liner, fails - f << "#{tag}=#{@session.get(tag)}\n" - end - elsif @variables.key?(tag) && ! @variables.empty?(key) then - f << "#{tag}=#{@variables.get(tag)}\n" - end - end - @session.subset("ENV").keys.each do |tag| - f << "#{tag}=#{@session.get(tag)}\n" - end - f << "\# #{@@session_end}\n" - end - end - rescue - return false - else - return true - end - end - - def logged_in_session(force_default=false) - if force_default || (@variables.default?('domain') && @variables.default?('project') && @variables.default?('username')) then - id = default_session - else - id = check_session - end - end - - def default_session - if @interface.true?('process:autologin') then - @variables.default('domain') - @variables.default('project') - @variables.default('username') - @variables.default('password') - check_session - else - @session_id = nil - end - end - - def check_session - @session.set('domain', @variables.get('domain').downcase) - @session.set('project', @variables.get('project').downcase) - @session.set('username', @variables.get('username').downcase) - @session.set('password', @variables.get('password').downcase) - new_session - @session.set('id', @session_id) - save_session - return @session_id - end - - def delete_session(id=nil) - File.delete(work_root,"#{@@session_prefix}#{id || @session_id}.ses") rescue false - end - - def cleanup_sessions(max_age=nil) - begin - now, age = Time.now, (max_age||@interface.get('process:timeout')).to_i - Dir.glob("{#{work_root},#{cache_root}/#{@@session_prefix}*").each do |s| - begin - if (now - File.mtime(s)) > age then - if FileTest.directory?(s) then - FileUtils::rm_r(s) - else - File.delete(s) - end - end - rescue - # maybe purged in the meantime - end - end - rescue - # maybe another process is busy - end - end - -end - -# templates - -class WWW - - def filled_template(title,text,showtime=false,refresh=0,refreshurl=nil) - template = @interface.get("template:#{@interface.get('tag:template')}") - template = @interface.get("template:status") if template.empty? - fullname = File.join(@interface.get('path:templates'),template) - @interface.set('log:templatename',template) - @interface.set('log:templatefile',fullname) - append_status(text) - htmreply = '' - if FileTest.file?(fullname) then - begin - htmreply = IO.read(fullname) - rescue - htmreply = '' - end - end - if refresh>0 then - if refreshurl then - metadata = "<meta http-equiv='refresh' content='#{refresh};#{refreshurl}'>" - else - metadata = "<meta http-equiv='refresh' content='#{refresh}'>" - end - else - metadata = '' - end - if ! htmreply || htmreply.empty? then - # in head: <link rel='stylesheet' href='/exaresource/exastyle.css'> - htmreply = <<-EOD - <html> - #{metadata} - <head> - <title>#{title}</title> - </head> - <body> - <h2>#{title}</h2> - <h4>#{Time.now}</h4> - #{text} - </body> - </html> - EOD - else - if showtime then - exa_template = "<h1>#{title}</h1>\n<h2>#{Time.now}</h2>\n#{text}\n" - else - exa_template = "<h1>#{title}</h1>#{text}\n" - end - htmreply = replace_template_placeholder(htmreply,exa_template,metadata) - end - htmreply - end - - def message(title,str='',showtime=false,refresh=0,refreshurl=nil) - if @cgi then - @cgi.out("cookie"=>[@cgi_cookie]) do - filled_template(title,str,showtime,refresh,refreshurl) - end - elsif @webrick_response then - @webrick_response['content-type'] = 'text/html' - @webrick_response.body = filled_template(title,str,showtime,refresh,refreshurl) - else - filled_template(title,str,showtime,refresh,refreshurl) - end - end - - def plaintext(str) - if @cgi then - @cgi.out('cookie'=>[@cgi_cookie],'content-type'=>'text/plain') do - str - end - elsif @webrick_response then - @webrick_response['content-type'] = 'text/plain' - @webrick_response.body = str - else - str - end - end - - def exareply(status='',url='',size='',comment='') - exaurl = @interface.get('process:exaurl') - str = "<?xml version='1.0'?>\n\n" - str << "<exa:reply xmlns:exa='#{@@namespace}'>\n" - str << " <exa:session>#{@session_id}</exa:session>\n" unless @session_id.empty? - str << " <exa:status>#{status}</exa:status>\n" unless (status || '').empty? - str << " <exa:url>#{exaurl}/#{url}</exa:url>\n" unless (url || '').empty? - str << " <exa:size>#{size}</exa:size>\n" unless (size || '').empty? - str << " <exa:comment>#{comment}</exa:comment>\n" unless (comment|| '').empty? - str << "</exa:reply>\n" - return str - end - - def append_status(str='') - if @interface.true?('trace:errors') then - if $! && $@ then - str << "<br/><br/><br/><em>Error:</em><br/><pre>#{$!}</pre><pre>" - str << $@.join("\n") - end - str << '<br/><br/><br/>' - str << status_data - str << '<em>Paths</em><br/>' - str << '<pre>' - @interface.subset('path:').each do |k,v| - if FileTest.directory?(v) then - if FileTest.writable?(v) then - str << "#{v} exists and is writable\n" - else - str << "#{v} is not writable\n" - end - else - str << "#{v} does not exist\n" - end - end - str << '</pre>' - end - str - end - - def simpleurl(url) - if url then url.sub(/(:80|:443)$/,'') else '' end - end - - def replace_exa_placeholders(data) - data.gsub(/([\"\'])\@exa\_([a-zA-Z0-9\-\_]+)\1/) do - quot, key, value = $1, $2, '' - begin - value = @variables.get(key) - rescue - value = '' - end - quot + value + quot - end - end - - def replace_url_placeholder(data) - data.gsub!(/(http:\/\/|\/+)*\@exa\_main\_url/, @interface.get('process:exaurl')) - replace_exa_placeholders(data) - end - - def replace_template_placeholder(data,template='',metadata='') - data.gsub!(/(http:\/\/|\/+)*\@exa\_main\_url/, @interface.get('process:exaurl')) - data.gsub!(/\@exa\_template/, template) - data.gsub!(/\@exa\_metadata/, metadata) - replace_exa_placeholders(data) - end - - def escaped(str) - str - end - -end - -# send files - -class WWW - - def send_file(filename,parse=false) # this can take a lot of memory, look for alternative (fastcgi ?) - begin - if filename =~ /\.pdf$/ then - mimetype, parse = 'application/pdf', false - elsif filename =~ /\.(html|htm)$/ then - mimetype, parse = 'text/html', true - else - mimetype, parse = 'text/plain', false - end - if FileTest.file?(filename) then - if @webrick_response then - begin - @webrick_response['content-type'] = mimetype - @webrick_response['content-length'] = FileTest.size?(filename) - if parse then - File.open(filename, 'rb') do |f| - @webrick_response.body = replace_url_placeholder(f.read) - end - else - @webrick_response.body = File.open(filename, 'rb') - end - rescue - else - return - end - elsif @cgi then - begin - # the following works ok, but stores the whole file in memory (see @cgi.out) - # - # File.open(filename, 'rb') do |f| - # @cgi.out('cookie'=>[@cgi_cookie],'connection'=>'close', 'length'=>File.size(filename), 'type'=>mimetype) do - # if parse then replace_url_placeholder(f.read) else f.read end - # end - # end - if parse then - File.open(filename, 'rb') do |f| - @cgi.out('cookie'=>[@cgi_cookie],'connection'=>'close', 'length'=>File.size(filename), 'type'=>mimetype) do - replace_url_placeholder(f.read) - end - end - else - @cgi.print(@cgi.header('cookie'=>[@cgi_cookie],'connection'=>'close', 'length'=>File.size(filename), 'type'=>mimetype)) - File.open(filename, 'rb') do |f| - while str = f.gets do - @cgi.print(str) - end - end - end - rescue - else - return - end - end - end - rescue - end - message('Error', "There is a problem with sending file #{File.basename(filename)}.") - end - - def send_htmlfile(filename,parse=false) - send_file(filename,parse) - end - def send_pdffile(filename) # this can take a lot of memory, look for alternative (fastcgi ?) - send_file(filename,false) - end - -end - -# tracing - -class WWW - - def show_vars(a=@variables,title='') - if a && a.length > 0 then - if title.empty? then - str = '' - else - str = "<em>#{title}</em>" - end - str << "<br/><pre>\n" - a.keys.sort.each do |k| - if k && a[k] && ! a[k].empty? then - if k == 'password' then - val = if a[k] == 'default' then 'default' else '******' end - else - # str << "#{k} => #{a[k].sub(/^\s+/moi,'').sub(/\s+$/moi,'')}\n" - val = a[k].to_s.strip - val.gsub!("&","&") - val.gsub!("<","<") - val.gsub!(">",">") - val.gsub!("\n","\n ") - end - str << "#{k} => #{val}\n" - end - end - str << "</pre><br/>\n" - return str - else - return '' - end - end - - def status_data - show_vars(@session , 'Session' ) + - show_vars(@variables, 'Variables' ) + - show_vars(@interface, 'Interface' ) + - show_vars(ENV , 'Environment') - end - - def report_status - check_template_file('status') - message('Status',status_data) - end - -end - -# attachments - -class WWW - - def extract_sent_files(dir) - files = Array.new - if @cgi then - @cgi.params.keys.each do |tag| - begin - if filename = @cgi[tag].original_filename then - files << extract_file_content(dir,filename,@cgi[tag]) unless filename.empty? - end - rescue - end - end - elsif @webrick_request then - @webrick_request.query.keys.each do |tag| - begin - if filename = @webrick_request.query[tag].filename then - files << extract_file_content(dir,filename,@webrick_request.query[tag]) unless filename.empty? - end - rescue - end - end - end - @interface.set('log:attachments', files.compact.uniq.join('|')) - end - - def extract_file_content(dir,filename,data) - filename = File.join(dir,File.basename(filename)) - begin - @interface.set('log:attachclass', data.class.inspect) - if data.class == Tempfile then - begin - File.copy(data.path,filename) - rescue - begin - File.open(filename,'wb') do |f| - File.open(data.path,'rb') do |g| - while str = g.gets do - f.write(str) - end - end - end - rescue - @interface.set('log:attachstate', "saving tempfile #{filename} failed (#{$!})") - else - @interface.set('log:attachstate', "tempfile #{filename} has been saved") - end - else - @interface.set('log:attachstate', "#{data.path} copied to #{filename}") - end - elsif data.class == String then - begin - File.open(filename,'wb') do |f| - f.write(data) - end - rescue - @interface.set('log:attachstate', "saving string #{filename} failed (#{$!})") - else - @interface.set('log:attachstate', "string #{filename} has been saved") - end - elsif data.class == StringIO then - begin - File.open(filename,'wb') do |f| - f.write(data.read) - end - rescue - @interface.set('log:attachstate', "saving stringio #{filename} failed (#{$!})") - else - @interface.set('log:attachstate', "stringio #{filename} has been saved") - end - else - @interface.set('log:attachstate', "unknown attachment class #{data.class.to_s}") - end - rescue - begin File.delete(filename) ; rescue ; end - else - begin File.delete(filename) if FileTest.size(filename) == 0 ; rescue ; end - end - return File.basename(filename) - end - -end - -# configuration - -class WWW - - def interface_base_name(str) - str.sub(/\.(pdf|htm|html)$/, '') - end - - def located_interface_file(filename) - ['configurations', 'runners', 'scripts'].each do |tag| - datafile = File.join(@interface.get("path:#{tag}"),filename) - if FileTest.file?(datafile+'.encrypted') then - return datafile + '.encrypted' - elsif FileTest.file?(datafile) then - return datafile - end - end - return nil - end - - def load_interface_file(filename=@@data_file) - reset_session() # no save yet - if datafile = located_interface_file(filename) then - nestedfiles = Array.new - begin - data = IO.read(datafile) || '' - unless data.empty? then - loop do # we need to load them recursively - done = false - data.gsub!(/^include\s*:\s*(.*?)\s*$/) do - includedname, done = $1, true - if nestedname = located_interface_file(includedname) then - begin - str = ("\n" + IO.read(nestedname) + "\n") || '' - rescue - nestedfiles << File.basename('-'+includedname) - '' - else - nestedfiles << File.basename('+'+includedname) - str - end - else - nestedfiles << File.basename('-'+includedname) - '' - end - end - break unless done - end - end - @interface.set('log:configurationfile', datafile + ' [' + nestedfiles.join(' ') + ']') - return data - rescue - end - end - @interface.set('log:configurationfile', filename + ' [not loaded]') - return nil - end - - def fetch_session_interface_variables(data) - data.scan(/^variable\s*:\s*(.*?)\s*\=\s*(.*?)\s*$/) do - @interface.set($1, $2) - end - return true - end - - def fetch_session_project_list(data) - projectlist, permitted = Array.new, false - data.scan(/^user\s*:\s*(.*?)\s*\,\s*(.*?)\s*\=\s*(.*?)\s*\,\s*(.*?)\s*$/) do - domain, username, password, projects = $1, $2, $3, $4 - if @session.match?('domain',domain) && @session.match?('username',username) then - if same_passwords(password) then - projectlist, permitted = @interface.resolved(projects).split(@@re_bar), true - break - end - end - end - if permitted then - @interface.set('log:projectlist', '['+projectlist.join(' ')+']') - if projectlist.length == 0 then - return nil - else - return projectlist - end - else - @interface.set('log:projectlist', '[no projects]') - return nil - end - end - - def fetch_session_command(data) - data.scan(/^process\s*:\s*(.*?)\s*\,\s*(.*?)\s*\=\s*(.*?)\s*$/) do - domain, process, command = $1, $2, $3 - if @session.match?('domain',domain) && @session.match?('process',process) then - @session.set('command', @interface.resolved(command)) - end - end - return @session.get('command') - end - - def fetch_session_settings(data) - data.scan(/^setting\s*:\s*(.*?)\s*\,\s*(.*?)\s*\,\s*(.*?)\s*\=\s*(.*?)\s*$/) do - domain, process, variable, value = $1, $2, $3, $4 - if @session.match?('domain',domain) && @session.match?('process',process) then - @interface.set(variable,value) - end - end - end - - def get_command(action) - # @session.set('action', action) - # if @session.get('process') == 'none' then - # @interface.set('log:child','yes') - # @session.set('process', action) - # end - if data = load_interface_file() then - fetch_session_interface_variables(data) - if projectlist = fetch_session_project_list(data) then - data.scan(/^project\s*:\s*(.*?)\s*\,\s*(.*?)\s*\=\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*$/) do - domain, project, gui, path, process = $1, $2, $3, $4, $5 - if @session.match?('domain',domain) then - if @session.match?('project',project) then - if projectlist.include?(project) then - @session.set('process', @interface.resolved(process)) - # break # no, else we end up in the parent (e.g. examplap instead of impose) - end - elsif ! action.empty? && project == action then - if projectlist.include?(action) then - @session.set('process', @interface.resolved(process)) - # break # no, else we end up in the parent (e.g. examplap instead of impose) - end - end - end - end - fetch_session_command(data) - fetch_session_settings(data) - end - end - return ! @session.nothing?('command') - end - - def get_file(filename) - @session.set('filename', filename) - if data = load_interface_file() then - fetch_session_interface_variables(data) - if projectlist = fetch_session_project_list(data) then - data.scan(/^project\s*:\s*(.*?)\s*\,\s*(.*?)\s*\=\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*$/) do - domain, project, gui, path, process = $1, $2, $3, $4, $5 - if @session.match?('domain',domain) then - guilist = @interface.resolved(gui).split(@@re_bar) - guilist.each do |g| - if /#{filename}$/ =~ g then - @session.set('gui', File.expand_path(@interface.resolved(g))) - @session.set('path', File.expand_path(@interface.resolved(path))) - @session.set('process', process) - break # take first matching interface - end - end - end - end - end - end - return ! (@session.nothing?('gui') && @session.nothing?('path') && @session.nothing?('process')) - end - - def get_path(url='') - if data = load_interface_file() then - fetch_session_interface_variables(data) - if projectlist = fetch_session_project_list(data) then - data.scan(/^project\s*:\s*(.*?)\s*\,\s*(.*?)\s*\=\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*$/) do - domain, project, gui, path, process = $1, $2, $3, $4, $5 - if @session.match?('domain',domain) && @session.match?('project',project) then - @session.set('url', url) - @session.set('gui', '') - @session.set('path', File.expand_path(@interface.resolved(path))) - @session.set('process', '') - end - end - end - end - return ! @session.nothing?('path') - end - - def get_gui() - if data = load_interface_file() then - fetch_session_interface_variables(data) - if projectlist = fetch_session_project_list(data) then - data.scan(/^project\s*:\s*(.*?)\s*\,\s*(.*?)\s*\=\s*(.*?)\s*,\s*(.*?)\s*,\s*(.*?)\s*$/) do - domain, project, gui, path, process = $1, $2, $3, $4, $5 - if @session.match?('domain',domain) && @session.match?('project',project) && projectlist.include?(project) then - @session.set('gui', File.expand_path(@interface.resolved(gui))) - @session.set('path', File.expand_path(@interface.resolved(path))) - @session.set('process', process) unless process == 'none' - break # take first matching interface - end - end - data.scan(/^admin\s*:\s*(.*?)\s*\,\s*(.*?)\s*\=\s*(.*?)\s*\,\s*(.*?)\s*$/) do - domain, project, task, option = $1, $2, $3, $4 - if @session.match?('domain',domain) && @session.match?('project',project) && projectlist.include?(project) then - @session.set('task', task) - @session.set('option', option) - break # take first matching task - end - end - end - end - return ! (@session.nothing?('gui') && @session.nothing?('path') && @session.nothing?('process')) - end - - def get_cfg() - if data = load_interface_file() then - fetch_session_interface_variables(data) - end - end - -end - -class WWW - - def send_reply(logdata='') - if @interface.true?('trace:run') then - send_result(logdata) - else - dir, tmp = dirname, tmp_path(dirname) - case @session.get('status') - when 'running: finished' then - resultname, replyname = 'result.pdf', 'reply.exa' - replyfile = File.join(tmp,replyname) - if FileTest.file?(replyfile) then - begin - data = IO.read(replyfile) - resultname = if data =~ /<exa:output>(.*?)<\/exa:output>/ then $1 else resultname end - rescue - plaintext(exareply('error in reply')) - return - end - end - resultfile = File.join(tmp,resultname) - if FileTest.file?(resultfile) then - if indirect?(resultfile) then - begin - File.makedirs(File.join(cache_root,dir)) - FileUtils::mv(resultfile,File.join(cache_root,dir,resultname)) - rescue - plaintext(exareply('unable to access cache')) - else - plaintext(exareply('big file', "cache/#{dir}/#{resultname}", "#{File.size?(resultfile)}")) - end - else - send_file(resultfile) - end - else - plaintext(exareply('no result')) - end - else # background, running, aborted - plaintext(exareply(@session.get('status'))) - end - end - end - - def send_url(fullname) - dir, tmp = dirname, tmp_path(dirname) - resultname, replyname = 'result.pdf', 'reply.exa' - replyfile = File.join(tmp,replyname) - resultfile = File.join(tmp,resultname) - targetname = File.join(cache_root,dir,resultname) - # make sure that there is no target left in case of an - # error; needed in case of given session name - if FileTest.directory?(File.join(cache_root,dir)) then - File.delete(targetname) rescue false - end - # now try to locate the file - if FileTest.file?(fullname) then - if indirect?(fullname) then - begin - # check if directory exists and (if so) delete left overs - File.makedirs(File.join(cache_root,dir)) - File.delete(targetname) rescue false - File.symlink(fullname,targetname) rescue message('Status',$!) - unless FileTest.file?(targetname) then - FileUtils::cp(fullname,targetname) rescue false - end - rescue - plaintext(exareply('unable to access cache')) - else - plaintext(exareply('big file', "cache/#{dir}/#{resultname}", "#{File.size?(fullname)}")) - end - else - send_file(fullname) - end - else - message('Status', 'The file is not found') - end - end - - def send_result(logdata='') - check_template_file('exalogin','exalogin-template.htm') - dir, tmp = dirname, tmp_path(dirname) - resultname, replyname, logname = 'result.pdf', 'reply.exa', 'log.htm' - case @session.get('status') - when 'running: background' then - if st = @session.get('starttime') then # fuzzy - st = Time.now.to_i if st.empty? - if (Time.now.to_i - st.to_i) > @interface.get('process:timeout').to_i then - message('Status', 'Your request has been aborted (timeout)',true) - else - message('Status', 'Your request is queued',true,5,'exastatus') - end - end - when 'running: busy' then - if st = @session.get('starttime') then # fuzzy - st = Time.now.to_i if st.empty? - if (Time.now.to_i - st.to_i) > @interface.get('process:timeout').to_i then - message('Status', 'Your request has been aborted (timeout)',true) - else - message('Status', 'Your request is being processed',true,5,'exastatus') - end - end - when 'running: aborted' then - message('Status', 'Your request has been aborted (timeout)',true) - when 'running: finished' then - if @interface.true?('trace:run') then - logfile = File.join(tmp,logname) - begin - if f = File.open(logname,'w') then - if logdata.empty? then - begin - logdata = IO.read('www-watch.out') - rescue - logdata = 'no log data' - end - end - f << filled_template('Log',"<pre>#{CGI::escapeHTML(logdata)}</pre>") - f.close - end - rescue - message('Error', '') - end - if FileTest.file?(logfile) then - begin - File.makedirs(File.join(cache_root,dir)) - FileUtils::mv(logfile,File.join(cache_root,dir,logname)) - rescue - logdata = "<br/><br/>unable to access cache</a>" - else - logdata = "<br/><br/><a href='/cache/#{dir}/#{logname}'>#{logname}</a>" - end - else - logdata = '' - end - else - logdata = '' - end - # todo: generate reply.exa if no reply - replyfile = File.join(tmp,replyname) - if FileTest.file?(replyfile) then - begin - data = IO.read(replyfile) - resultname = if data =~ /<exa:output>(.*?)<\/exa:output>/ then $1 else resultname end - rescue - message('Error','There is a problem in handling this request (invalid reply).') - return - end - end - resultfile = File.join(tmp,resultname) - if FileTest.file?(resultfile) then - if indirect?(resultfile) then - begin - File.makedirs(File.join(cache_root,dir)) - FileUtils::mv(resultfile,File.join(cache_root,dir,resultname)) - rescue - str = "<br/><br/>unable to access cache</a>" - else - str = "<br/><br/><a href='/cache/#{dir}/#{resultname}'>#{resultname}</a> (#{File.size?(resultname)} bytes)" - end - message('Result', 'You can pick up the result here:' + str + logdata) - else - send_file(resultfile) - end - else - message('Error', 'There is a problem in handling this request (no result file).' + logdata) - end - end - end - -end diff --git a/Master/texmf-dist/scripts/context/ruby/www/login.rb b/Master/texmf-dist/scripts/context/ruby/www/login.rb deleted file mode 100644 index 1c88a97e6ad..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/www/login.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'www/lib' - -# basic login - -class WWW - - def handle_login() - check_template_file('login','exalogin.htm') - set('password', '') - message('Login','') - end - -end diff --git a/Master/texmf-dist/scripts/context/ruby/wwwclient.rb b/Master/texmf-dist/scripts/context/ruby/wwwclient.rb deleted file mode 100644 index d41541a095d..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/wwwclient.rb +++ /dev/null @@ -1,677 +0,0 @@ -#!/usr/bin/env ruby - -# a direct request is just passed on -# -# exaclient --direct --request=somerequest.exa --result=somefile.pdf -# -# in an extended request the filename in the template file is replaced by the filename -# given on the command line; templates are located on the current path and at parent -# directories (two levels); the filename is expanded to a full path -# -# exaclient --extend --template=tmicare-l-h.exa --file=somefile.xml --result=somefile.pdf -# -# a constructed request is build out of the provided filename and action; the filename is -# expanded to a full path -# -# exaclient --construct --action=tmicare-s-h.exa --file=somefile.xml --result=somefile.pdf -# -# in all cases, the result is either determined by a switch or taken from a reply file - -banner = ['WWWClient', 'version 1.0.0', '2003-2006', 'PRAGMA ADE/POD'] - -$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! - -require 'base/switch' -require 'base/logger' - -require 'timeout' -require 'thread' -require 'rexml/document' -require 'net/http' - -class File - - def File.backtracked(filename,level=3) - if level > 0 && filename && ! filename.empty? then - if FileTest.file?(filename) then - filename - else - File.backtracked('../'+filename,level-1) - end - else - filename - end - end - - def File.expanded(filename) - File.expand_path(filename) - end - -end - -class Commands - - include CommandBase - -end - -class Commands - - @@namespace = "xmlns:exa='http://www.pragma-ade.com/schemas/example.rng'" - @@randchars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "abcdefghijklmnopqrstuvwxyz" - - def traceback - "(error: #{$!})" + "\n -- " + $@.join("\n >>") - end - - def pdf(action,filename,enabled) - if enabled && FileTest.file?(filename) then - begin - report("pdf action #{action} on #{filename}") - case action - when 'close' then system("pdfclose --all") - when 'open' then system("pdfopen --file #{filename}") - end - rescue - # forget about it - end - end - end - - def status(replyfile,str) # when block, then ok - begin - # def status(*whatever) - # end - File.open(replyfile,'w') do |f| - report("saving reply info in '#{replyfile}'") - f.puts("<?xml version='1.0'?>\n\n") - f.puts("<exa:reply #{@@namespace}>\n") - if block_given? then - f.puts(" <exa:status>ok</exa:status>\n") - f.puts(" #{yield}\n") - else - f.puts(" <exa:status>error</exa:status>\n") - end - f.puts(" <exa:comment>" + str + "</exa:comment>\n") - f.puts("</exa:reply>\n") - f.close - report("saving status: #{str}") - end - rescue - report("saving reply info in '#{replyfile}' fails") - ensure - exit - end - exit # to be real sure - end - - - def boundary_string (length) # copied from webrick/utils - rand_max = @@randchars.size - ret = "" - length.times do - ret << @@randchars[rand(rand_max)] - end - ret.upcase - end - -end - -class Commands - - @@connecttimeout = 10*60 # ten minutes - @@processtimeout = 60*60 # an hour - @@polldelay = 5 # 5 seconds - - def main - - datatemplate = @commandline.option('template') - datafile = @commandline.option('file') - dataaction = @commandline.option('action') - - if ! datatemplate.empty? then - report("template '#{datatemplate}' specified without --construct") - report("aborting") - elsif ! dataaction.empty? then - report("action data '#{dataaction}' specified without --construct or --extend") - report("aborting") - elsif ! datafile.empty? then - report("action file '#{datafile}' specified without --construct or --extend") - report("aborting") - else - report("assuming --direct") - direct() - end - - end - - def construct - - requestfile = @commandline.option('request') - replyfile = @commandline.option('reply') - - datatemplate = @commandline.option('template') - datafile = @commandline.option('file') - dataaction = @commandline.option('action') - - domain = @commandline.option('domain') - project = @commandline.option('project') - username = @commandline.option('username') - password = @commandline.option('password') - - threshold = @commandline.option('threshold') - - datablob = '' - - begin - datablob = IO.read(datatemplate) - rescue - datablob = '' - else - begin - request = REXML::Document.new(datablob) - if e = REXML::XPath.match(request.root,"/exa:request/exa:data") then - datablob = e.to_s.chomp - end - rescue - datablob = '' - end - end - - begin - File.open(requestfile,'w') do |f| - f.puts "<?xml version='1.0'?>\n" - f.puts "<exa:request #{@@namespace}>\n" - f.puts " <exa:application>\n" - f.puts " <exa:action>#{dataaction}</exa:action>\n" unless dataaction.empty? - f.puts " <exa:filename>#{datafile}</exa:filename>\n" unless datafile.empty? - f.puts " <exa:threshold>#{threshold}</exa:threshold>\n" unless threshold.empty? - f.puts " </exa:application>\n" - f.puts " <exa:client>\n" - f.puts " <exa:domain>#{domain}</exa:domain>\n" - f.puts " <exa:project>#{project}</exa:project>\n" - f.puts " <exa:username>#{username}</exa:username>\n" - f.puts " <exa:password>#{password}</exa:password>\n" - f.puts " </exa:client>\n" - if datablob.empty? then - f.puts " <exa:data/>\n" - else - f.puts " #{datablob.chomp}\n" - end - f.puts "</exa:request>" - end - rescue - status(replyfile,"unable to create '#{requestfile}'") - end - - direct() - - end - - def extend - - requestfile = @commandline.option('request') - replyfile = @commandline.option('reply') - - datatemplate = @commandline.option('template') - datafile = @commandline.option('file') - dataaction = @commandline.option('action') - - threshold = @commandline.option('threshold') - - if datatemplate.empty? then - status(replyfile,"invalid data template '#{datatemplate}'") - else - begin - if FileTest.file?(datatemplate) && oldrequest = IO.read(datatemplate) then - request, done = REXML::Document.new(oldrequest), false - if ! threshold.empty? && e = REXML::XPath.match(request.root,"/exa:request/exa:application/exa:threshold") then - e.text, done = threshold, true - end - if ! dataaction.empty? && e = REXML::XPath.match(request.root,"/exa:request/exa:application/exa:action") then - e.text, done = dataaction, true - end - if ! datafile.empty? && e = REXML::XPath.match(request.root,"/exa:request/exa:application/exa:filename") then - e.text, done = datafile, true - end - # - if ! threshold.empty? && e = REXML::XPath.match(request.root,"/exa:request/exa:application") then - e = e.add_element('exa:threshold') - e.add_text(threshold.to_s) - done = true - end - # - report("nothing replaced in template file") unless done - begin - File.open(requestfile,'w') do |f| - f.puts(newrequest.to_s) - end - rescue - status(replyfile,"unable to create '#{requestfile}'") - end - else - status(replyfile,"unable to read data template '#{datatemplate}'") - end - rescue - status(replyfile,"unable to handle data template '#{datatemplate}'") - end - end - - direct() - - end - - def direct - - requestpath = @commandline.option('path') - requestfile = @commandline.option('request') - replyfile = @commandline.option('reply') - resultfile = @commandline.option('result') - datatemplate = @commandline.option('template') - datafile = @commandline.option('file') - threshold = @commandline.option('threshold') - address = @commandline.option('address') - port = @commandline.option('port') - session_id = @commandline.option('session') - exaurl = @commandline.option('exaurl') - - exaurl = "/#{exaurl}" unless exaurl =~ /^\// - - address.sub!(/^http\:\/\//io) do - '' - end - address.sub!(/\:(\d+)$/io) do - port = $1 - '' - end - - autopdf = @commandline.option('autopdf') - - dialogue = nil - - resultfile.sub!(/\.[a-z]+?$/, '') # don't overwrite the source - - unless requestpath.empty? then - begin - if FileTest.directory?(requestpath) then - if Dir.chdir(requestpath) then - report("gone to path '#{requestpath}'") - else - status(replyfile,"unable to go to path '#{requestpath}") - end - else - status(replyfile,"unable to locate '#{requestpath}'") - end - rescue - status(replyfile,"unable to handle '#{requestpath}'") - end - end - - datafile = File.expand_path(datafile) unless datafile.empty? - datatemplate = File.backtracked(datatemplate,3) unless datatemplate.empty? - - # request must be valid - - status(replyfile,'no request file') if requestfile.empty? - status(replyfile,"invalid request file '#{requestfile}'") unless FileTest.file?(requestfile) - - begin - request = IO.readlines(requestfile).join('') - request = REXML::Document.new(request) - status(replyfile,'invalid request (no request)') unless request.root.fully_expanded_name=='exa:request' - status(replyfile,'invalid request (no application block)') unless request.elements['exa:request'].elements['exa.application'] == nil # explicit nil test needed - rescue REXML::ParseException - status(replyfile,'invalid request (invalid xml file)') - rescue - status(replyfile,'invalid request (invalid file)') - else - report("using request file '#{requestfile}'") - end - - # request can force session_id - - if session_id && session_id.empty? then - begin - id = request.elements['exa:request'].elements['exa:application'].elements['exa:session'].text - rescue Exception - id = '' - ensure - if id && ! id.empty? then - session_id = id - end - end - end - - # request can overload reply name - - begin - rreplyfile = request.elements['exa:request'].elements['exa:application'].elements['exa:output'].text - rescue Exception - rreplyfile = nil - ensure - if rreplyfile && ! rreplyfile.empty? then - replyfile = rreplyfile - report("reply file '#{replyfile} set by request'") - else - report("using reply file '#{replyfile}'") - end - end - - # request can overload result name - - begin - rresultfile = request.elements['exa:request'].elements['exa:application'].elements['exa:result'] - rescue Exception - rresultfile = nil - ensure - if rresultfile && ! rresultfile.empty? then - resultfile = rresultfile - report("result file '#{resultfile}' set by request") - else - report("using result file '#{resultfile}'") - end - end - - # try to connect to server - - start_time = Time.now - - processtimeout = begin @commandline.option('timeout').to_i rescue @@processtimeout end - processtimeout = @@processtimeout if processtimeout == 0 # 'xx'.to_i => 0 - - dialogue = start_dialogue(address, port, processtimeout) - - if dialogue then - # continue - else - status(replyfile,'no connection') - end - - # post request - - timeout (@@processtimeout-10) do # -10 so that we run into this one first - begin - report("posting request of type '#{exaurl}'") - report("using session id '#{session_id}'") if session_id && ! session_id.empty? - firstline, chunks, total = nil, 0, 0 - body, boundary, crlf = '', boundary_string(32), "\x0d\x0a" - body << '--' + boundary + crlf - body << "Content-Disposition: form-data; name=\"exa:request\"" - body << crlf - body << "Content-Type: text/plain" - body << crlf + crlf - body << request.to_s - body << crlf + '--' + boundary + crlf -if session_id && ! session_id.empty? then - body << "Content-Disposition: form-data; name=\"exa:session\"" - body << "Content-Type: text/plain" - body << crlf + crlf - body << session_id - body << crlf + '--' + boundary + crlf -end - begin - File.open(datafile,'rb') do |df| - body << "Content-Disposition: form-data; name=\"filename\"" - body << "Content-Type: text/plain" - body << crlf + crlf - body << datafile - body << crlf + '--' + boundary + crlf - body << "Content-Disposition: form-data; name=\"fakename\" ; filename=\"#{datafile}\"" - body << "Content-Type: application/octetstream" - body << "Content-Transfer-Encoding: binary" - body << crlf + crlf - body << df.read - body << crlf + '--' + boundary + '--' + crlf - end - rescue - # skip - end - headers = Hash.new - headers['content-type'] = "multipart/form-data; boundary=#{boundary}" - headers['content-length'] = body.length.to_s - begin - File.open(resultfile,'wb') do |rf| - begin - # firstline is max 1024 but ok for reply - dialogue.post(exaurl,body,headers) do |str| - if ! firstline || firstline.empty? then - report('receiving result') if total == 0 - firstline = str - end - total += 1 - rf.write(str) - end - rescue - report("forced close #{traceback}") - end - end - rescue - status(replyfile,'cannot open file') - end - begin - File.delete(resultfile) if File.zero?(resultfile) - rescue - end - unless FileTest.file?(resultfile) then - report("deleting empty resultfile") - begin - File.delete(resultfile) - rescue - # nice try, an error anyway - end - status(replyfile,'empty file') - else - n, id, status = 0, '', '' - loop do - again = false - if ! dialogue then - again = true - elsif firstline =~ /(\<exa:reply)/moi then - begin - reply = REXML::Document.new(firstline) - id = (REXML::XPath.match(reply.root,"/exa:reply/exa:session/text()") || '').to_s - status = (REXML::XPath.match(reply.root,"/exa:reply/exa:status/text()") || '').to_s - rescue - report("error in parsing reply #{traceback}") - break - else - report("status: #{status}") - if (status =~ /^running\s*\:\s*(background|busy)$/i) && (! id.empty?) then - report("waiting for status reply (#{n*@@polldelay})") - again = true - end - end - end - if again then - n += 1 - sleep(@@polldelay) # todo: duplicate when n > 1 - unless dialogue then - report('reestablishing connection') - dialogue = start_dialogue(address, port, processtimeout) - end - if dialogue then - begin - File.open(resultfile,'wb') do |rf| - begin - body = "id=#{id}" - headers = Hash.new - headers['content-type'] = "application/x-www-form-urlencoded" - headers['content-length'] = body.length.to_s - total, firstline = 0, '' - dialogue.post("/exastatus",body,headers) do |str| - if ! firstline || firstline.empty? then - firstline = str - end - total += 1 - rf.write(str) - end - rescue - report("forced close #{traceback}") - dialogue = nil - again = true - end - end - begin - File.delete(resultfile) if File.zero?(resultfile) - rescue - end - rescue - report("error in opening file #{traceback}") - status(replyfile,'cannot open file') - end - else - report("unable to make a connection") - status(replyfile,'unable to make a connection') # exit - end - else - break - end - end - case firstline - when /<\?xml\s*version=.*?\?>\s*<exa:reply/moi then - begin - File.delete(replyfile) if FileTest.file?(replyfile) - resultfile = replyfile if File.rename(resultfile,replyfile) - rescue - end - report("reply saved in '#{resultfile}'") - when /\%PDF\-/io then - report("done, file #{resultfile}, type pdf, #{total} chunks, #{File.size? rescue 0} bytes") - if resultfile =~ /\.pdf$/i then - report("file identified as 'pdf'") - elsif resultfile =~ /\..*$/o - report("result file suffix should be 'pdf'") - else - newresultfile = resultfile + '.pdf' - newresultfile.sub!(/\.pdf\.pdf/io, '.pdf') - pdf('close',newresultfile,autopdf) - begin - File.delete(newresultfile) if FileTest.file?(newresultfile) - resultfile = newresultfile if File.rename(resultfile,newresultfile) - rescue - report("adding 'pdf' suffix to result name failed") - else - report("'pdf' suffix added to result name") - end - end - report("result saved in '#{resultfile}'") - pdf('open',resultfile,autopdf) - status(replyfile,'ok') do - "<exa:filename>#{resultfile}</exa:filename>" - end - when /html/io then - report("done, file #{resultfile}, type html, #{total} chunks, #{File.size? rescue 0} bytes") - if resultfile =~ /\.(htm|html)$/i then - report("file identified as 'html'") - elsif resultfile =~ /\..*$/o - report("result file suffix should be 'htm'") - else - newresultfile = resultfile + '.htm' - begin - File.delete(newresultfile) if FileTest.file?(newresultfile) - resultfile = newresultfile if File.rename(resultfile,newresultfile) - rescue - report("adding 'htm' suffix to result name failed") - else - report("'htm' suffix added to result name") - end - end - report("result saved in '#{resultfile}'") - status(replyfile,'ok') do - "<exa:filename>#{resultfile}</exa:filename>" - end - else - report("no result file, first line #{firstline}") - status(replyfile,'no result file') - end - end - rescue TimeoutError - report("aborted due to time out") - status(replyfile,'time out') - rescue - report("aborted due to some problem #{traceback}") - status(replyfile,"no answer #{traceback}") - end - end - - begin - report("run time: #{Time.now-start_time} seconds") - rescue - end - - end - - def start_dialogue(address, port, processtimeout) - timeout(@@connecttimeout) do - report("trying to connect to #{address}:#{port}") - begin - begin - if dialogue = Net::HTTP.new(address, port) then - # dialogue.set_debug_output $stderr - dialogue.read_timeout = processtimeout # set this before start - if dialogue.start then - report("connected to #{address}:#{port}, timeout: #{processtimeout}") - else - retry - end - else - retry - end - rescue - sleep(2) - retry - else - return dialogue - end - rescue TimeoutError - return nil - rescue - return nil - end - end - end - -end - -logger = Logger.new(banner.shift) -commandline = CommandLine.new - -commandline.registerflag('autopdf') - -commandline.registervalue('path' , '') - -commandline.registervalue('request' , 'request.exa') -commandline.registervalue('reply' , 'reply.exa') -commandline.registervalue('result' , 'result') - -commandline.registervalue('template' , '') -commandline.registervalue('file' , '') -commandline.registervalue('action' , '') -commandline.registervalue('timeout' , '') - -commandline.registervalue('domain' , 'default') -commandline.registervalue('project' , 'default') -commandline.registervalue('username' , 'guest') -commandline.registervalue('password' , 'anonymous') -commandline.registervalue('exaurl' , 'exarequest') -commandline.registervalue('threshold' , '0') -commandline.registervalue('session' , '') - -commandline.registervalue('address' , 'localhost') -commandline.registervalue('port' , '80') - -commandline.registeraction('direct' , '[--path --request --reply --result --autopdf]') -commandline.registeraction('construct', '[--path --request --reply --result --autopdf] --file --action') -commandline.registeraction('extend' , '[--path --request --reply --result --autopdf] --file --action --template') - -commandline.registeraction('direct') -commandline.registeraction('construct') -commandline.registeraction('extend') - -commandline.registerflag('verbose') -commandline.registeraction('help') -commandline.registeraction('version') - -commandline.expand - -Commands.new(commandline,logger,banner).send(commandline.action || 'main') diff --git a/Master/texmf-dist/scripts/context/ruby/wwwserver.rb b/Master/texmf-dist/scripts/context/ruby/wwwserver.rb deleted file mode 100644 index 13d5d13125c..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/wwwserver.rb +++ /dev/null @@ -1,293 +0,0 @@ -#!/usr/bin/env ruby - -banner = ['WWWServer', 'version 1.0.0', '2003-2006', 'PRAGMA ADE/POD'] - -$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! - -require 'base/switch' -require 'base/logger' - -require 'monitor' - -# class WWW < Monitor -# end -# class Server < Monitor -# end - -require 'www/lib' -require 'www/dir' -require 'www/login' -require 'www/exa' - -require 'tempfile' -require 'ftools' -require 'webrick' - -class Server - - attr_accessor :document_root, :work_path, :logs_path, :port_number, :exa_url, :verbose, :trace, :direct - - def initialize(logger) - @httpd = nil - @document_root = '' - @work_path = '' - @logs_path = '' - @port_number = 8061 - @exa_url = 'http://localhost:8061' - @logger = logger - @n_of_clients = 500 - @request_timeout = 5*60 - @verbose = false - @trace = false - @direct = false - end - - def report(str) - @logger.report(str) if @logger - end - - def setup - if @document_root.empty? then - rootpath = File.expand_path($0) - @document_root = File.expand_path(File.join(File.dirname(rootpath),'..','documents')) - unless FileTest.directory?(@document_root) then # todo: optional - loop do - prevpath = rootpath.dup - rootpath = File.dirname(rootpath) - if prevpath == rootpath then - break - else - checkpath = File.join(rootpath,'documents') - # report("locating: #{checkpath}") - if FileTest.directory?(checkpath) then - @document_root = checkpath - break - else - checkpath = File.join(rootpath,'docroot/documents') - # report("locating: #{checkpath}") - if FileTest.directory?(checkpath) then - @document_root = checkpath - break - end - end - end - end - end - end - @document_root = File.join(Dir.pwd, 'documents') unless FileTest.directory?(@document_root) - unless FileTest.directory?(@document_root) then - report("invalid document root: #{@document_root}") - exit - else - report("using document root: #{@document_root}") - end - # - @work_path = File.expand_path(File.join(@document_root,'..','work')) if @work_path.empty? - # begin File.makedirs(@work_path) ; rescue ; end # no, let's auto-temp - if ! FileTest.directory?(@work_path) || ! FileTest.writable?(@work_path) then - @work_path = File.expand_path(File.join(Dir.tmpdir,'exaserver','work')) - begin File.makedirs(@logs_path) ; rescue ; end - end - report("using work path: #{@work_path}") - # - @logs_path = File.expand_path(File.join(@document_root,'..','logs')) if @logs_path.empty? - # begin File.makedirs(@logs_path) ; rescue ; end # no, let's auto-temp - if ! FileTest.directory?(@logs_path) || ! FileTest.writable?(@logs_path) then - @logs_path = File.expand_path(File.join(Dir.tmpdir,'exaserver','logs')) - begin File.makedirs(@logs_path) ; rescue ; end - end - report("using log path: #{@logs_path}") - # - if @logs_path.empty? then - @logfile = $stderr - @accfile = $stderr - else - @logfile = File.join(@logs_path,'exa-info.log') - @accfile = File.join(@logs_path,'exa-access.log') - begin File.delete(@logfile) ; rescue ; end - begin File.delete(@accfile) ; rescue ; end - end - # - begin - @httpd = WEBrick::HTTPServer.new( - :DocumentRoot => @document_root, - :DocumentRootOptions => { :FancyIndexing => false }, - :DirectoryIndex => ['index.html','index.htm','showcase.pdf'], - :Port => @port_number.to_i, - :Logger => WEBrick::Log.new(@logfile, WEBrick::Log::INFO), # DEBUG - :RequestTimeout => @request_timeout, - :MaxClients => @n_of_clients, - :AccessLog => [ - [ @accfile, WEBrick::AccessLog::COMMON_LOG_FORMAT ], - [ @accfile, WEBrick::AccessLog::REFERER_LOG_FORMAT ], - [ @accfile, WEBrick::AccessLog::AGENT_LOG_FORMAT ], - # :CGIPathEnv => ENV["PATH"] # PATH environment variable for CGI. - ] - ) - rescue - report("starting server at port: #{@port_number} failed") - exit - else - report("running server at port: #{@port_number}") - end - - begin - # - @httpd.mount_proc("/dir") do |request,reply| - report("accepting /dir") if @verbose - web_session(request,reply).handle_dir - end - @httpd.mount_proc("/login") do |request,reply| - report("accepting /login") if @verbose - web_session(request,reply).handle_login - end - @httpd.mount("/cache", WEBrick::HTTPServlet::FileHandler, File.join(@work_path,'cache')) - # @httpd.mount_proc("/cache") do |request,reply| - # WEBrick::HTTPServlet::FileHandler(@httpd,@work_path) # not ok - # end - @httpd.mount_proc("/exalogin") do |request,reply| - report("accepting /exalogin") if @verbose - web_session(request,reply).handle_exalogin - end - @httpd.mount_proc("/exadefault") do |request,reply| - report("accepting /exadefault") if @verbose - web_session(request,reply).handle_exadefault - end - @httpd.mount_proc("/exainterface") do |request,reply| - report("accepting /exainterface") if @verbose - web_session(request,reply).handle_exainterface - end - @httpd.mount_proc("/exarequest") do |request,reply| - report("accepting /exarequest") if @verbose - web_session(request,reply).handle_exarequest - end - @httpd.mount_proc("/exacommand") do |request,reply| - report("accepting /exacommand") if @verbose - web_session(request,reply).handle_exacommand - end - @httpd.mount_proc("/exastatus") do |request,reply| - report("accepting /exastatus") if @verbose - web_session(request,reply).handle_exastatus - end - @httpd.mount_proc("/exaadmin") do |request,reply| - report("accepting /exaadmin") if @verbose - web_session(request,reply).handle_exaadmin - end - # - rescue - report("problem in starting server: #{$!}") - end - [:INT, :TERM, :EXIT].each do |signal| - trap(signal) do - @httpd.shutdown - end - end - end - - def start - unless @httpd then - setup - @httpd.start - end - end - - def stop - @httpd.shutdown if @httpd - end - - def restart - stop - start - end - - private - - def web_session(request,reply) - www = WWW.new(@httpd,request,reply) - www.set('path:work', @work_path) - www.set('path:logs', @logs_path) - www.set('path:root', File.dirname(@document_root)) - www.set('process:exaurl', @exa_url) - www.set('trace:errors','yes') if @trace - www.set('process:background', 'no') if @direct - return www - end - -end - -class Commands - - include CommandBase - - def start - if server = setup then server.start end - end - - def stop - if server = setup then server.stop end - end - - def restart - if server = setup then server.restart end - end - - private - - def setup - server = Server.new(logger) - server.document_root = @commandline.option('root') - server.verbose = @commandline.option('verbose') - if @commandline.option('forcetemp') then - server.work_path = Dir.tmpdir + '/exa/work' - server.logs_path = Dir.tmpdir + '/exa/logs' - [server.work_path,server.logs_path].each do |d| - begin - File.makedirs(d) unless FileTest.directory?(d) - rescue - report("unable to create #{d}") - exit - end - unless FileTest.writable?(d) then - report("unable to access #{d}") - exit - end - end - else - server.work_path = @commandline.option('work') - server.logs_path = @commandline.option('logs') - end - server.port_number = @commandline.option('port') - server.exa_url = @commandline.option('url') - server.trace = @commandline.option('trace') - server.direct = @commandline.option('direct') - return server - end - -end - -logger = Logger.new(banner.shift) -commandline = CommandLine.new - -commandline.registervalue('root' , '') -commandline.registervalue('work' , '') -commandline.registervalue('logs' , '') -commandline.registervalue('address', 'localhost') -commandline.registervalue('port' , '8061') -commandline.registervalue('url' , 'http://localhost:8061') - -commandline.registeraction('start' , 'start the server [--root --forcetemp --work --logs --address --port --url]') -commandline.registeraction('stop' , 'stop the server') -commandline.registeraction('restart', 'restart the server') - -commandline.registerflag('forcetemp') -commandline.registerflag('direct') -commandline.registerflag('verbose') -commandline.registerflag('trace') - -commandline.registeraction('help') -commandline.registeraction('version') - -commandline.expand - -Commands.new(commandline,logger,banner).send(commandline.action || 'start') - diff --git a/Master/texmf-dist/scripts/context/ruby/wwwwatch.rb b/Master/texmf-dist/scripts/context/ruby/wwwwatch.rb deleted file mode 100644 index 0faa45aec44..00000000000 --- a/Master/texmf-dist/scripts/context/ruby/wwwwatch.rb +++ /dev/null @@ -1,497 +0,0 @@ -#!/usr/bin/env ruby - -banner = ['WWWWatch', 'version 1.0.0', '2003-2006', 'PRAGMA ADE/POD'] - -$: << File.expand_path(File.dirname($0)) ; $: << File.join($:.last,'lib') ; $:.uniq! - -require 'base/switch' -require 'base/logger' - -require 'www/common' - -require 'monitor' -require 'fileutils' -require 'ftools' -require 'tempfile' -require 'timeout' -require 'thread' - -class Watch < Monitor - - include Common - - @@session_prefix = '' - @@check_factor = 4 - @@process_timeout = 1*60*60 - @@fast_wait_loop = false - - @@session_line = /^\s*(?![\#\%])(.*?)\s*\=\s*(.*?)\s*$/o - @@session_begin = 'begin exa session' - @@session_end = 'end exa session' - - attr_accessor :root_path, :work_path, :create, :cache_path, :delay, :max_threads, :max_age, :verbose - - def initialize(logger) # we need to register all @vars here becase of the monitor - @threads = Hash.new - @files = Array.new - @stats = Hash.new - @skips = Hash.new - @root_path = '' - @work_path = Dir.tmpdir - @cache_path = @work_path - @last_action = Time.now - @delay = 1 - @max_threads = 5 - @max_age = @@process_timeout - @logger = logger - @verbose = false - @create = false - @onlyonerun = false - # [:INT, :TERM, :EXIT].each do |signal| - # trap(signal) do - # kill - # exit # rescue false - # end - # end - # at_exit do - # kill - # end - end - - def trace - if @verbose && @logger then - @logger.report("exception: #{$!})") - $@.each do |t| - @logger.report(">> #{t}") - end - end - end - - def report(str) - @logger.report(str) if @logger - end - - def setup - @threads = Hash.new - @files = Array.new - @stats = Hash.new - @skips = Hash.new - @root_path = File.expand_path(File.join(File.dirname(Dir.pwd),'.')) if @root_path.empty? - @work_path = File.expand_path(File.join(@root_path,'work','watch')) if @work_path.empty? - # @cache_path = File.expand_path(File.join(@root_path,'work','cache')) if @cache_path.empty? - @cache_path = File.expand_path(File.join(File.dirname(@work_path),'cache')) if @cache_path.empty? - if @create then - begin File.makedirs(@work_path) ; rescue ; end - begin File.makedirs(@cache_path) ; rescue ; end - end - unless File.writable?(@work_path) then - @work_path = File.expand_path(File.join(Dir.tmpdir,'work','watch')) - if @create then - begin File.makedirs(@work_path) ; rescue ; end - end - end - unless File.writable?(@cache_path) then - @cache_path = File.expand_path(File.join(Dir.tmpdir,'work','cache')) - if @create then - begin File.makedirs(@cache_path) ; rescue ; end - end - end - unless File.writable?(@work_path) then - puts "no valid work path: #{@work_path}" - exit! rescue false # no checking, no at_exit done - end - unless File.writable?(@cache_path) then - puts "no valid cache path: #{@cache_path}" ; # no reason to exit - end - @last_action = Time.now - report("watching path #{@work_path}") if @verbose - end - - def lock(lck) - begin - report("watchdog: locking #{lck}") if @verbose - File.open(lck,'w') do |f| - f << Time.now - end - rescue - trace - end - end - - def unlock(lck) - begin - report("watchdog: unlocking #{lck}") if @verbose - File.delete(lck) - rescue - trace - end - end - - def kill - @threads.each do |t| - t.kill rescue false - end - end - - def restart - @files = Array.new - @skips = Hash.new - @stats = Hash.new - kill # threads - end - - def collect - begin - @files = Array.new - Dir.glob("#{@work_path}/#{@@session_prefix}*.ses").each do |sessionfile| - sessionfile = File.expand_path(sessionfile) - begin - if @threads.key?(sessionfile) then - # leave alone - elsif (Time.now - File.mtime(sessionfile)) > @max_age.to_i then - # delete - FileUtils::rm_r(sessionfile) rescue false - FileUtils::rm_r(sessionfile.sub(/ses$/,'dir')) rescue false - FileUtils::rm_r(sessionfile.sub(/ses$/,'lck')) rescue false - begin - FileUtils::rm_r(File.join(@cache_path, File.basename(sessionfile.sub(/ses$/,'dir')))) - rescue - report("watchdog: problems in cache cleanup #{$!}") # if @verbose - end - @stats.delete(sessionfile) rescue false - @skips.delete(sessionfile) rescue false - report("watchdog: removing session #{sessionfile}") if @verbose - elsif ! @skips.key?(sessionfile) then - @files << sessionfile - report("watchdog: checking session #{sessionfile}") if @verbose - end - rescue - # maybe purged in the meantime - end - end - rescue - if File.directory?(@work_path) then - @files = Array.new - else - # maybe dir is deleted (manual cleanup) - restart - end - end - begin - Dir.glob("#{@cache_path}/*.dir").each do |dirname| - begin - if (Time.now - File.mtime(dirname)) > @max_age.to_i then - begin - FileUtils::rm_r(dirname) - rescue - report("watchdog: problems in cache cleanup #{$!}") # if @verbose - end - end - rescue - # maybe purged in the meantime - end - end - rescue - end - end - - def purge - begin - Dir.glob("#{@work_path}/#{@@session_prefix}*").each do |sessionfile| - sessionfile = File.expand_path(sessionfile) - begin - if (Time.now - File.mtime(sessionfile)) > @max_age.to_i then - begin - if FileTest.directory?(sessionfile) then - FileUtils::rm_r(sessionfile) - else - File.delete(sessionfile) - end - rescue - end - begin - @stats.delete(sessionfile) - @skips.delete(sessionfile) - rescue - end - report("watchdog: purging session #{sessionfile}") if @verbose - end - rescue - # maybe purged in the meantime - end - end - rescue - end - end - - def loaded_session_data(filename) - begin - if data = IO.readlines(filename) then - return data if (data.first =~ /^[\#\%]\s*#{@@session_begin}/o) && (data.last =~ /^[\#\%]\s*#{@@session_end}/o) - end - rescue - trace - end - return nil - end - - def load(sessionfile) - # we assume that we get an exception when the file is locked - begin - if data = loaded_session_data(sessionfile) then - report("watchdog: loading session #{sessionfile}") if @verbose - vars = Hash.new - data.each do |line| - begin - if line.chomp =~ /^(.*?)\s*\=\s*(.*?)\s*$/o then - key, value = $1, $2 - vars[key] = value - end - rescue - end - end - return vars - else - return nil - end - rescue - trace - return nil - end - end - - def save(sessionfile, vars) - begin - report("watchdog: saving session #{sessionfile}") if @verbose - if @stats.key?(sessionfile) then - @stats[sessionfile] = File.mtime(sessionfile) - elsif @stats[sessionfile] == File.mtime(sessionfile) then - else - # construct data first - str = "\# #{@@session_begin}\n" - for k,v in vars do - str << "#{k}=#{v}\n" - end - str << "\# #{@@session_end}\n" - # save as fast as possible - File.open(sessionfile,'w') do |f| - f.puts(str) - end - end - rescue - report("watchdog: unable to save session #{sessionfile}") if @verbose - trace - return false - else - return true - end - end - - def launch - begin - @files.each do |sessionfile| - if @threads.length < @max_threads then - begin - if ! @skips.key?(sessionfile) && (vars = load(sessionfile)) then - if (id = vars['id']) && vars['status'] then - if vars['status'] == 'running: background' then - @last_action = Time.now - @threads[sessionfile] = Thread.new(vars, sessionfile) do |vars, sessionfile| - begin - report("watchdog: starting thread #{sessionfile}") if @verbose - dir = File.expand_path(sessionfile.sub(/ses$/,'dir')) - lck = File.expand_path(sessionfile.sub(/ses$/,'lck')) - start_of_run = Time.now - start_of_job = start_of_run.dup - max_time = @max_age - begin - start_of_job = vars['starttime'].to_i || start_of_run - start_of_job = start_of_run if start_of_job == 0 - rescue - start_of_job = Time.now - end - begin - max_runtime = vars['maxtime'].to_i || @max_age - max_runtime = @max_age if max_runtime == 0 - max_runtime = max_runtime - (Time.now.to_i - start_of_job.to_i) - rescue - max_runtime = @max_age - end - lock(lck) - if max_runtime > 0 then - command = vars['command'] || '' - if ! command.empty? then - vars['status'] = 'running: busy' - vars['timeout'] = max_runtime.to_s - save(sessionfile,vars) - timeout(max_runtime) do - begin - command = command_string(dir,command,'process.log') - report("watchdog: #{command}") if @verbose - system(command) - rescue TimeoutError - vars['status'] = 'running: timeout' - rescue - trace - vars['status'] = 'running: aborted' - else - vars['status'] = 'running: finished' - vars['runtime'] = sprintf("%.02f",(Time.now - start_of_run)) - vars['endtime'] = Time.now.to_i.to_s - end - end - else - vars['status'] = 'running: aborted' # no command - end - else - vars['status'] = 'running: aborted' # not enough time - end - save(sessionfile,vars) - unlock(lck) - report("watchdog: ending thread #{sessionfile}") if @verbose - @threads.delete(sessionfile) - rescue - trace - end - end - else - report("watchdog: skipping - id (#{vars['id']}) / status (#{vars['status']})") if @verbose - end - if @onlyonerun then - @skips[sessionfile] = true - else - @skips.delete(sessionfile) - end - else - # not yet ok - end - else - # maybe a lock - end - rescue - trace - end - else - break - end - end - rescue - trace - end - end - - def wait - begin - # report(Time.now.to_s) if @verbose - loop do - @threads.delete_if do |k,v| - begin - v == nil || v.stop? - rescue - true - else - false - end - end - if @threads.length == @max_threads then - if @delay > @max_threads then - sleep(@delay) - else - sleep(@max_threads) - end - break if @@fast_wait_loop - else - sleep(@delay) - break - end - end - rescue - trace - end - end - - def check - begin - time = Time.now - if (time - @last_action) > @@check_factor*@max_age then - report("watchdog: cleanup") if @verbose - @stats = Hash.new - @last_action = time - kill - end - rescue - trace - end - end - - def cycle - loop do - begin - collect - launch - wait - check - rescue - trace - report("watchdog: some problem, restarting loop") - end - end - end - -end - -class Commands - - include CommandBase - - def watch - if watch = setup then - watch.cycle - else - report("provide valid work path") - end - end - def main - watch - end - - private - - def setup - if watch = Watch.new(logger) then - watch.root_path = @commandline.option('root') - watch.work_path = @commandline.option('work') - watch.cache_path = @commandline.option('cache') - watch.create = @commandline.option('create') - watch.verbose = @commandline.option('verbose') - begin - watch.max_threads = @commandline.option('threads').to_i - rescue - watch.max_threads = 5 - end - watch.setup - end - return watch - end - -end - -logger = Logger.new(banner.shift) -commandline = CommandLine.new - -commandline.registervalue('root', '') -commandline.registervalue('work', '') -commandline.registervalue('cache', '') -commandline.registervalue('threads', '5') - -commandline.registerflag('create') - -commandline.registeraction('watch', '[--work=path] [--root=path] [--create]') - -commandline.registerflag('verbose') -commandline.registeraction('help') -commandline.registeraction('version') - -commandline.expand - -Commands.new(commandline,logger,banner).send(commandline.action || 'main') |