diff options
Diffstat (limited to 'Master/texmf-dist/tex/context/base/data-sch.lua')
-rw-r--r-- | Master/texmf-dist/tex/context/base/data-sch.lua | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/Master/texmf-dist/tex/context/base/data-sch.lua b/Master/texmf-dist/tex/context/base/data-sch.lua new file mode 100644 index 00000000000..e68b6cd01b9 --- /dev/null +++ b/Master/texmf-dist/tex/context/base/data-sch.lua @@ -0,0 +1,142 @@ +if not modules then modules = { } end modules ['data-sch'] = { + version = 1.001, + comment = "companion to luat-lib.mkiv", + author = "Hans Hagen, PRAGMA-ADE, Hasselt NL", + copyright = "PRAGMA ADE / ConTeXt Development Team", + license = "see context related readme files" +} + +local http = require("socket.http") +local ltn12 = require("ltn12") + +local gsub, concat, format = string.gsub, table.concat, string.format + +local trace_schemes = false trackers.register("resolvers.schemes",function(v) trace_schemes = v end) + +schemes = schemes or { } + +schemes.cached = { } +schemes.cachepath = caches.definepath("schemes") +schemes.threshold = 24 * 60 * 60 + +directives.register("schemes.threshold", function(v) schemes.threshold = tonumber(v) or schemes.threshold end) + +local cached, loaded, reused = schemes.cached, { }, { } + +local finders, openers, loaders = resolvers.finders, resolvers.openers, resolvers.loaders + +function schemes.curl(name,cachename) + local command = "curl --silent --create-dirs --output " .. cachename .. " " .. name -- no protocol .. "://" + os.spawn(command) +end + +function schemes.fetch(protocol,name,handler) + local cachename = schemes.cachepath() .. "/" .. gsub(name,"[^%a%d%.]+","-") + cachename = gsub(cachename,"[\\]", "/") -- cleanup + if not cached[name] then + statistics.starttiming(schemes) + if not io.exists(cachename) or (os.difftime(os.time(),lfs.attributes(cachename).modification) > schemes.threshold) then + cached[name] = cachename + if handler then + if trace_schemes then + logs.report("schemes","fetching '%s', protocol '%s', method 'built-in'",name,protocol) + end + io.flush() + handler(protocol,name,cachename) + else + if trace_schemes then + logs.report("schemes","fetching '%s', protocol '%s', method 'curl'",name,protocol) + end + io.flush() + schemes.curl(name,cachename) + end + end + if io.exists(cachename) then + cached[name] = cachename + if trace_schemes then + logs.report("schemes","using cached '%s', protocol '%s', cachename '%s'",name,protocol,cachename) + end + else + cached[name] = "" + if trace_schemes then + logs.report("schemes","using missing '%s', protocol '%s'",name,protocol) + end + end + loaded[protocol] = loaded[protocol] + 1 + statistics.stoptiming(schemes) + else + if trace_schemes then + logs.report("schemes","reusing '%s', protocol '%s'",name,protocol) + end + reused[protocol] = reused[protocol] + 1 + end + return cached[name] +end + +function finders.schemes(protocol,filename,handler) + local foundname = schemes.fetch(protocol,filename,handler) + return finders.generic(protocol,foundname,filetype) +end + +function openers.schemes(protocol,filename) + return openers.generic(protocol,filename) +end + +function loaders.schemes(protocol,filename) + return loaders.generic(protocol,filename) +end + +-- could be metatable + +function schemes.install(protocol,handler) + loaded [protocol] = 0 + reused [protocol] = 0 + finders[protocol] = function (filename,filetype) return finders.schemes(protocol,filename,handler) end + openers[protocol] = function (filename) return openers.schemes(protocol,filename) end + loaders[protocol] = function (filename) return loaders.schemes(protocol,filename) end +end + +local function http_handler(protocol,name,cachename) + local tempname = cachename .. ".tmp" + local f = io.open(tempname,"wb") + local status, message = http.request { + url = name, + sink = ltn12.sink.file(f) + } + if not status then + os.remove(tempname) + else + os.remove(cachename) + os.rename(tempname,cachename) + end +end + +schemes.install('http',http_handler) +schemes.install('https') +schemes.install('ftp') + +statistics.register("scheme handling time", function() + local l, r = { }, { } + for k, v in table.sortedhash(loaded) do + if v > 0 then + l[#l+1] = k .. ":" .. v + end + end + for k, v in table.sortedhash(reused) do + if v > 0 then + r[#r+1] = k .. ":" .. v + end + end + local n = #l + #r + if n > 0 then + l = (#l > 0 and concat(l)) or "none" + r = (#r > 0 and concat(r)) or "none" + return format("%s seconds, %s processed, threshold %s seconds, loaded: %s, reused: %s", + statistics.elapsedtime(schemes), n, schemes.threshold, l, r) + else + return nil + end +end) + +--~ trace_schemes = true +--~ print(schemes.fetch("http","http://www.pragma-ade.com/show-man.pdf",http_handler)) |