/*  $VER: Cache.www 2.1 (15.1.96) Stephan Lichtendahl
Caching of inlined images and HTML documents on harddisk */

cachedir='AmiTCP:Cache/'

if ~show(l,'rexxsupport.library') then
  if ~addlib('rexxsupport.library',0,-30,0) then
    exit
if ~show(l,'rexxdossupport.library') then
  if ~addlib('rexxdossupport.library',0,-30,2) then
    exit

hit=0
zoek=0
nl='0a'x
cr='0d'x
Update=''
Port='AMOSAIC.1'
OPTIONS RESULTS

parse arg args
if ~ReadArgs(args,'Save/S,Load/S,Remove/S,Port,Update/K') | Port = '?' then do
  say 'Usage: Cache.www [Save] to get/put images in current AMosaic'
  say 'document from/in cache, Save will save HTML document as well.'
  say 'Remove will remove the current AMosaic document from cache,'
  say 'and every image in it which is currently visable (ie. loaded).'
  say 'Cache.www Load reloads the current cached document from WWW.'
  say 'Cache.www Update <AMosaic program> will update the hotlists'
  say 'env(arc):mosaic/.mosaic-hotlist-default and start AMosaic.'
  return 0
end
if Update ~= '' then do
  if exists(cachedir'DoHTMLlist') then
    call UpdateHL
  address command 'Run >Nil: 'Update
  return 0
end
address value Port

if ~Load then do
  'fetch images IMAGE'
  call open(1input,cachedir'ImageList','R')
  list = nl||readch(1input,65534)
  call close(1input)
end

if ~Load & ~Remove then do
  do i=1 for image.0
    urlnaam=image.i.url
    av=image.i.current
    nieuw.i=''

    if left(urlnaam,17) = 'file://localhost/' then do
      if ~av then
        'fetch inline url 'urlnaam
     end
    else do
      call MkLocal
      nr = pos(nl||uremote||nl,list)

      if nr = 0 & av then do
        address command 'Echo >>'cachedir'ImageList "'uremote'"'
        list=list||uremote||nl
        call ChkTree
      end
      if nr > 0 & ~av then do
        nieuw.i=ulocal
        hit=2
      end
      if av then do
        nieuw.i=ulocal
        call open(2input,image.i.filename,'R')
        call open(2output,cachedir||ulocal,'W')
        do until eof(2input)
          call writech(2output,readch(2input,65535))
        end
        call close(2input)
        call close(2output)
      end
    end

  end
end

if Remove then do
  do i=1 for image.0
    if image.i.current then do
      urlnaam=image.i.url
      if left(urlnaam,17) ~= 'file://localhost/' then
        call MkLocal
      else do
        ulocal = substr(urlnaam,18)
        call MkRemote
      end
      call DelItem
    end
  end

  if zoek > 0 then do
    call open(1output,cachedir'Imagelist','W')
    call writech(1output,substr(list,2))
    call close(1output)
  end
end

'get url'
urlnaam = result
if left(urlnaam,17) ~= 'file://localhost/' then
  call MkLocal
else do
  ulocal = substr(urlnaam,18)
  if left(ulocal,10) = 'T:temphtml' then
    uremote=0
  else
    uremote=''
end

if uremote = 0 & (Load | Save) then do
  'jump back'
  return 0
end

call open(3input,cachedir'HTMLlist','R')
list = nl||readch(3input,65534)
call close(3input)

if uremote = '' & Load then do
  call MkRemote
  if uremote ~= '' then
    'jump url http://'uremote
end

if Save then do
  if uremote = '' then do
    call MkRemote
    if uremote = '' then do
      address command 'GetString "Local document - change URL for remote links" String "http://'ulocal'" Var newurl Global'
      if RC ~= 0 then
        return 0
      else do
        urlnaam = getvar('newurl')
        call deletevar('newurl')
        call MkLocal
      end
    end
  end

  hit=hit+1
  saveto=cachedir||ulocal

  nr = pos(nl||uremote||nl,list)
  if nr = 0 then do
    address command 'Echo >>'cachedir'HTMLlist "'uremote'"'
    list=list||uremote||nl
    call ChkTree

    'fetch title'
    titel = translate(result,,nl'"'cr)
    address command 'Echo >>'cachedir'Cache.html "<A HREF=*"/'saveto'*">'titel'</A><BR>"'
    address command 'Echo >>'cachedir'DoHTMLlist "+'uremote'"'

    zoek=1
    zoek.0=urlnaam
    vervang.0='/'saveto
  end
end

if Remove then do
  if uremote ~= 0 & (zoek = 0 | zoek = image.0) then do
    if uremote = '' then
      call MkRemote
    if uremote ~= '' then do
      call DelItem

      call open(3output,cachedir'HTMLlist','W')
      call writech(3output,substr(list,2))
      call close(3output)

      call open(5input,cachedir'Cache.html','R')
      cachtml = readch(5input,65535)
      call close(5input)

      nr = pos('/'cachedir||ulocal'"',cachtml)
      if nr > 0 then do
        startnr = lastpos(nl,cachtml,nr)+1
        stopnr = pos(nl,cachtml,nr)+1
        cachtml = delstr(cachtml,startnr,stopnr-startnr)

        call open(5output,cachedir'Cache.html','W')
        call writech(5output,cachtml)
        call close(5output)
      end

      address command 'Echo >>'cachedir'DoHTMLlist "-'uremote'"'
      'jump url http://'uremote
    end
  end

  if zoek > 0 then
    call MultiFR
end

if hit>0 then do
  if hit = 2 then
    do n=1 until ~exists(saveto)
      saveto='T:temphtml'n
    end

  'fetch source'
  inhoud = result
  nr = max(pos('<html',inhoud),pos('<HTML',inhoud))
  if nr > 0 then do
    startnr=nr+5
    stopnr = pos('>',inhoud,startnr)
    if startnr ~= stopnr then
      inhoud = delstr(inhoud,startnr,stopnr-startnr)
  end
  if nr > 1 then
    inhoud = substr(inhoud,nr)

  urlstam = left(urlnaam,lastpos('/',urlnaam)-1)
  urlroot = left(urlnaam,pos('/',urlnaam,8)-1)
  call ChkLinks
  zkinhoud=''
  info='<A HREF="mailto:s.e.m.lichtendahl@et.tudelft.nl">WWWCache 2.1 © S.Lichtendahl</A>'
  call ChkCache
  if hit=2 then
    inhoud=inhoud'<H6>This is a temporal page created by 'info'</H6>'

  call open(4output,saveto,'W')
  call writech(4output,inhoud)
  call close(4output)
  inhoud=''

  'jump url file://localhost/'saveto
  do i=1 for image.0
    if nieuw.i ~= '' then
      'fetch inline url /'cachedir||nieuw.i
  end
  if hit = 2 then
    call delete(saveto)

  if zoek > 0 then
    call MultiFR
end
exit 0

MkLocal:
  nr = pos('://',urlnaam)+3
  if nr = 3 then
    nr = pos(':',urlnaam)+1
  uremote = substr(urlnaam,nr)

  zoeknr = pos(':',uremote)
  if zoeknr > 0 then
    if left(uremote,10) = 'localhost/' then
      ulocal = substr(uremote,zoeknr+1)
    else do
      midnr = pos('/',uremote,zoeknr+1)
      ulocal = delstr(uremote,zoeknr,midnr-zoeknr)
    end
  else
    ulocal=uremote

  if right(ulocal,1) = '/' then
    ulocal=ulocal'.html'
return 0

MkRemote:
  if left(ulocal,length(cachedir)) ~= cachedir then
    uremote=''
  else do
    ulocal = substr(ulocal,length(cachedir)+1)
    if right(ulocal,6) = '/.html' then
      uremote = left(ulocal,length(ulocal)-5)
    else
      uremote=ulocal

    if pos(nl||uremote||nl,list) = 0 then do
      stopnr=0
      nr = pos(':'uremote||nl,list)
      if nr > 0 then do
        startnr = lastpos(nl,list,nr)+1
        stopnr = pos(nl,list,nr)

       end
      else do
        nr = pos('/',uremote)
        uleft = left(uremote,nr-1)':'
        uright = substr(uremote,nr)nl

        nr = pos(uright,list)
        do while nr > 0 & stopnr = 0
          startnr = lastpos(nl,list,nr)+1
          zoeknr = pos(nl,list,nr)
          if substr(list,startnr,length(uleft)) = uleft then
            stopnr=zoeknr

          nr = pos(uright,list,zoeknr+1)
        end
      end

      if stopnr > 0 then 
        uremote = substr(list,startnr,stopnr-startnr)
      else
        uremote=''
    end

  end
return 0

ChkTree:
  zoeknr = pos('/',ulocal)
  do while zoeknr > 0
    pad = cachedir||left(ulocal,zoeknr-1)
    if ~exists(pad) then
      call makedir(pad)

    zoeknr = pos('/',ulocal,zoeknr+1)
  end
return 0

DelItem:
  nr = pos(nl||uremote||nl,list)
  if nr > 0 then do
    list = delstr(list,nr+1,length(uremote)+1)

    zoeknr = lastpos('/',ulocal'/')
    do until zoeknr = 0 | nr = 0
      pad = cachedir||left(ulocal,zoeknr-1)
      nr = delete(pad)
      if nr then
        say pad 'deleted.'

      zoeknr = lastpos('/',ulocal,zoeknr-1)
    end

    zoek.zoek='/'cachedir||ulocal
    vervang.zoek='http://'uremote
    zoek=zoek+1
  end
return 0

ChkLinks:
  delta=0
  zkinhoud = upper(inhoud)
  zoeknr = pos('<A',zkinhoud)
  do while zoeknr > 0

    zoeknr = verify(zkinhoud,nl cr,,zoeknr+2)
    if substr(zkinhoud,zoeknr,4) ~= 'HREF' then
      zklen=1
    else do
      zoeknr = verify(zkinhoud,nl cr,,zoeknr+4)
      if substr(zkinhoud,zoeknr,1) ~= '=' then
        zklen=1
      else do
        zoeknr = verify(zkinhoud,nl cr,,zoeknr+1)

        if substr(zkinhoud,zoeknr,1) = '"' then
          zoeknr=zoeknr+1
        else do
          inhoud = insert('"',inhoud,zoeknr+delta-1)
          delta=delta+1
        end
        stopnr = pos('>',zkinhoud,zoeknr)
        zklen=stopnr-zoeknr

        urlnaam = substr(zkinhoud,zoeknr,zklen)
        if pos('://',urlnaam) = 0 then
          call ReplUrl
        if right(urlnaam,1) ~= '"' then do
          inhoud = insert('"',inhoud,stopnr+delta-1)
          delta=delta+1
        end

      end
    end
    zoeknr = pos('<A',zkinhoud,zoeknr+zklen)
  end

  delta=0
  zkinhoud = upper(inhoud)
  zoeknr = pos('SRC',zkinhoud)
  do while zoeknr > 0

    nr = verify(zkinhoud,nl cr,'M',zoeknr-1)
    if nr ~= zoeknr-1 then
      zklen=1
    else do
      zoeknr = verify(zkinhoud,nl cr,,zoeknr+3)
      if substr(zkinhoud,zoeknr,1) ~= '=' then
        zklen=1
      else do
        zoeknr = verify(zkinhoud,nl cr,,zoeknr+1)

        if substr(zkinhoud,zoeknr,1) = '"' then
          zoeknr=zoeknr+1
        else do
          inhoud = insert('"',inhoud,zoeknr+delta-1)
          delta=delta+1
        end
        stopnr = verify(zkinhoud,'">'nl cr,'M',zoeknr)+1
        zklen=stopnr-zoeknr

        urlnaam = substr(zkinhoud,zoeknr,zklen)
        if pos('://',urlnaam) = 0 then
          call ReplUrl
        if right(urlnaam,1) ~= '"' then do
          inhoud = insert('"',inhoud,stopnr+delta-2)
          delta=delta+1
        end

      end
    end
    zoeknr = pos('SRC',zkinhoud,zoeknr+zklen)
  end

  delta=0
  zkinhoud = upper(inhoud)
  zoeknr = pos('ACTION',zkinhoud)
  do while zoeknr > 0

    zoeknr = verify(zkinhoud,nl cr,,zoeknr+6)
    if substr(zkinhoud,zoeknr,1) ~= '=' then
      zklen=1
    else do
      zoeknr = verify(zkinhoud,'"'nl cr,,zoeknr+1)
      stopnr = pos('"',zkinhoud,zoeknr)
      zklen=stopnr-zoeknr

      urlnaam = substr(zkinhoud,zoeknr,zklen)
      if pos('://',urlnaam) = 0 then
        call ReplUrl
    end
    zoeknr = pos('ACTION',zkinhoud,zoeknr+zklen)
  end
return 0

ReplUrl:
  nr = pos(':',urlnaam)
  if nr>0 then
    if left(urlnaam,5) = 'HTTP:' then do
      urlnaam = substr(urlnaam,6)
      inhoud = delstr(inhoud,zoeknr+delta,5)
      zoeknr=zoeknr+5
      delta=delta-5
      nr=0
    end

  if nr=0 then
    if left(urlnaam,1) ~= '#' then do
      if left(urlnaam,1) = '/' then
        tekst=urlroot
      else do
        tekst=urlstam

        do while left(urlnaam,3) = '../'
          urlnaam = substr(urlnaam,4)
          inhoud = delstr(inhoud,zoeknr+delta,3)
          zoeknr=zoeknr+3
          delta=delta-3
          tekst = left(tekst,lastpos('/',tekst)-1)
        end

        tekst=tekst'/'
      end

      inhoud = insert(tekst,inhoud,zoeknr+delta-1)
      delta=delta+length(tekst)
    end
return 0

ChkCache:
  do i=1 for image.0
    if nieuw.i ~= '' then do
      nr = pos(image.i.url'"',inhoud)
      if nr = 0 then
        inhoud=inhoud'<H6>Error: Image URL 'image.i.url' not found by 'info' Please mail URL of this page</H6>'
      else do

        inhoud = delstr(inhoud,nr,length(image.i.url))
        inhoud = insert('/'cachedir||nieuw.i,inhoud,nr-1)
      end
    end
  end

  if hit ~= 2 then do
    'fetch links HREF'
    do i=1 for href.0
      urlnaam=href.i.url
      if left(urlnaam,17) ~= 'file://localhost/' then do
        call MkLocal
        nr = pos(nl||uremote||nl,list)
        if nr > 0 then do

          nr = pos(urlnaam,inhoud)
          do while nr > 0
            zklen=length(urlnaam)
            tekst=substr(inhoud,nr+zklen,1)

            if tekst='#' | tekst='"' then
              if pos('ACTION',upper(substr(inhoud,nr-11,10))) = 0 then do

                inhoud = delstr(inhoud,nr,zklen)
                inhoud = insert('/'cachedir||ulocal,inhoud,nr-1)
              end

            nr = pos(urlnaam,inhoud,nr+zklen)
          end

        end
      end
    end

  end
return 0

MultiFR:
  startnr=2
  stopnr = pos(nl,list,2)
  do while stopnr > 0
    urlnaam = 'http://'substr(list,startnr,stopnr-startnr)
    call MkLocal

    q=0
    call open(6input,cachedir||ulocal,'R')
    inhoud = readch(6input,65535)
    call close(6input)

    do i=0 for zoek
      nr = pos(zoek.i,inhoud)
      do while nr > 0
        zklen=length(zoek.i)
        tekst=substr(inhoud,nr+zklen,1)

        if tekst='#' | tekst='"' then
          if pos('ACTION',upper(substr(inhoud,nr-11,10))) = 0 then do
            q=1
            inhoud = delstr(inhoud,nr,zklen)
            inhoud = insert(vervang.i,inhoud,nr-1)
            zklen=length(vervang.i)
          end

        nr = pos(zoek.i,inhoud,nr+zklen)
      end
    end                                                         

    if q then do
      call open(6output,cachedir||ulocal,'W')
      call writech(6output,inhoud)
      call close(6output)
      say cachedir||ulocal 'updated.'
    end

    startnr=stopnr+1
    stopnr = pos(nl,list,startnr)
  end
return 0

UpdateHL:
  call open(3input,cachedir'DoHTMLlist','R')
  list = readch(3input,65535)
  call close(3input)

  call open(7input,'Env:Mosaic/.mosaic-hotlist-default','R')
  inhoud = readch(7input,65535)
  call close(7input)

  cachtml=''
  startnr=1
  stopnr = pos(nl,list)
  do while stopnr > 0
    tekst = substr(list,startnr,1)
    urlnaam = 'http://'substr(list,startnr+1,stopnr-startnr-1)
    call MkLocal

    if tekst = '-' then do
      zoeknr = pos('file://localhost/'cachedir||ulocal,inhoud)
      if zoeknr > 0 then do
        nr = pos(nl,inhoud,zoeknr+17)+2
        inhoud = delstr(inhoud,zoeknr,nr-zoeknr)
        zoeknr=zoeknr-1
        urlnaam='http://'uremote
      end
    end
    if tekst = '+' then do
      if pos('/'cachedir||ulocal,inhoud) > 0 then
        zoeknr=0
      else do
        urlnaam='file://localhost/'cachedir||ulocal

        zoeknr = pos('http://'uremote,inhoud)
        if zoeknr > 0 then do
          nr = pos(nl,inhoud,zoeknr+7)+1
          inhoud = delstr(inhoud,zoeknr,nr-zoeknr)
          zoeknr=zoeknr-1
          inhoud = insert('©',inhoud,zoeknr)

         end
        else do
          zoeknr = pos('Default',inhoud)+7

          if cachtml = '' then do
            call open(5input,cachedir'Cache.html','R')
            cachtml = readch(5input,65535)
            call close(5input)
          end

          tekst='/'cachedir||ulocal'">'
          midnr = pos(tekst,cachtml)
          if midnr = 0 then
            titel = 'URL: http://'uremote
          else do
            midnr=midnr+length(tekst)
            nr = pos('<',cachtml,midnr)
            titel = strip(substr(cachtml,midnr,nr-midnr))
          end
          inhoud = insert('©'titel||nl,inhoud,zoeknr)
        end

      end
    end

    if zoeknr > 0 then do
      parse value date() with datum maand jaar .
      dag = left(date('W'),3)
      inhoud = insert(urlnaam dag maand datum time() jaar||nl,inhoud,zoeknr)
    end

    startnr=stopnr+1
    stopnr = pos(nl,list,startnr)
  end

  call delete(cachedir'DoHTMLlist')

  call open(7output,'Env:Mosaic/.mosaic-hotlist-default','W')
  call writech(7output,inhoud)
  call close(7output)
  call open(7output,'EnvArc:Mosaic/.mosaic-hotlist-default','W')
  call writech(7output,inhoud)
  call close(7output)
return 0

