*    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    
*
*  KONTROLA_ZALOH.PRG: program kontroluje existenci zaloh v danem adresari - sleduje data vytvoreni a velikosti
*
* 2017-04-27 - se dvema parametry vypisuje i kompletni seznam zalohovych souboru s datem vytvoreni a delkou
* 2017-05-02 - detekuje se i prazdna zaloha (soubor je mensi nez 55Bytes)
* 2017-05-15 - u souboru, vytvorenych po 19:00, se o den posune datum vytvoreni
* 2017-05-15 - hlida i postgresove dumpy, ktere maji priponu .pgdump
* 2017-07-13 - u postgresovych dumpu se bere datum vytvoreni z nazvu, protoze jsou stahovany z sftp a jako datum vytvoreni maji datum prenosu
* 2017-07-25 - u postgresovych dumpu posunut datum o jednicku, jinak se dnesni soubor hlasil vzdy jako chybejici
*            - vynechava adresare, obsahujici "\jlv\"
*            - delka souboru je zobrazena retezem hvezdicek pro rychly nahled velkych souboru
* 2018-03-11 - vynechavaji se podadresare \archiv
* 2018-03-28 - zarovnany texty, delky souboru se zobrazuji na desetiny megabyte
* 2019-03-11 - vynechavaji se podadresare \stc
* 2019-12-09 - omezena maximalni delka nazvu
* 2020-07-03 - novy format jmen souboru, vzdy jmeno konci rrrr-mm-dd
* 2020-07-14 - smaze prebytecne a duplicitni zalohy, pokud jsou nejmene 13 dni stare
* 2020-09-14 - zjednoduseni designu
* 2021-05-13 - loguje i zbyle misto na disku
*
*    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    *    

PARAM adresar_zaloh, i_seznam_souboru

vysledek = " v.2021-05-14"
vysledek = vysledek + crlf + "[2T#B]informace o zalohach z deseti poslednich dni, v hlavicce jsou posledni cifry datumu" + m.crlf
vysledek = vysledek + crlf + "[2T#B]vyznam symbolu: <b>#</b> - zaloha chybi, <b>&lt;</b> - mensi nez obvykle, <b>x</b> - o hodne mensi, <b>0</b> - prazdna "
clos data
crea table ( ".\soubory_zaloh") (adresar c(99), nazev c(99), atrib c(1), delka N(11), vytvoreno D, pocet_dni I, checksum C(22), co_s_tim C(22), rozsudek C(99))

DO priprav_seznam_souboru

COPY ALL TO .\sssouubory_zaloh

SELECT nazev, ROUND(AVG(delka), 0) as avg_delka, SPACE(66) as rozsudek, 00.0 as body FROM soubory_zaloh GROUP BY 1 ORDER BY 1 INTO TABLE (  + ".\soubory_zaloh2")

SCAN
   SCATTER FIELDS nazev, avg_delka memvar
   SELECT soubory_zaloh
   rozsudek = ""
   body = 0
   koeficient = 2.1    && dava snizujici vahu starsim zaloham, takze napr. kdyz chybi dnesni zaloha, je to vaznejsi, nez kdyz chybi 7 dni stara
   FOR ii = 0 to 9
       LOCATE FOR nazev = m.nazev .and. pocet_dni = m.ii
       DO CASE
       CASE .not. FOUND()
          rozsudek = m.rozsudek + "# "
       CASE delka < 55
          rozsudek = m.rozsudek + "0 "
          body = body + .1 * m.koeficient
       CASE delka < m.avg_delka * .3
          rozsudek = m.rozsudek + "x "
          body = body + .3 * m.koeficient
       CASE delka < m.avg_delka * .8
          rozsudek = m.rozsudek + "&lt; "
          body = body + .7 * m.koeficient
       OTHERWISE
          rozsudek = m.rozsudek + ". "
          body = body + m.koeficient
       ENDCASE
       koeficient = SQRT(m.koeficient)
       repl rozsudek with allt(str(m.ii)) + "  " + m.rozsudek 
   ENDFOR 
   SELECT soubory_zaloh2
   GATHER FIELDS rozsudek, body memvar
ENDSCAN

SELECT soubory_zaloh2
REPLACE FOR ". . . . . . . . . ." $ rozsudek rozsudek with ". .     O.K.    . ."
REPLACE ALL avg_delka WITH ROUND(avg_delka/1024/1024, 1)
REPLACE FOR avg_delka > 20 avg_delka WITH ROUND(avg_delka,  0)
REPLACE FOR avg_delka > 99 avg_delka WITH ROUND(avg_delka, -1)

max_delka_nazvu = 0
SCAN
    max_delka_nazvu = MAX(m.max_delka_nazvu, LEN(ALLTRIM(nazev)))
    REPLACE rozsudek WITH ALLT(rozsudek) + " " + PADL(ALLTRIM(STR(avg_delka,7,1)),7," ") + "MB " + delka2stars(avg_delka)
ENDSCAN 
max_delka_nazvu = MAX(m.max_delka_nazvu, 44) + 2

REPL ALL nazev WITH LEFT(ALLTRIM(nazev) + " ________________________________________", m.max_delka_nazvu + 2)

seznam_pripon = ""
FOR ii = 0 to 9
    seznam_pripon = m.seznam_pripon + " " + RIGHT(DTOS(DATE() - m.ii), 1)
ENDFOR 

o_adresar = "\):*(/"
SCAN
     zacatek_cesty = LEFT(nazev, AT("\", nazev, 2))
     IF m.zacatek_cesty # m.o_adresar
         o_adresar = m.zacatek_cesty
         o_adresar_1 = LEFT("======= " + UPPER(ALLTRIM(m.o_adresar)) + " ======================================", m.max_delka_nazvu-1)
         vysledek = vysledek + "<BR>" + crlf + "[2T#K]" + m.o_adresar_1 + m.seznam_pripon + " ============"
     ENDIF 

     DO CASE
     CASE body > 8
           vysledek = vysledek + crlf + "[2T#g]"
     CASE body > 6
           vysledek = vysledek + crlf + "[2T#r]"
     OTHER
           vysledek = vysledek + crlf + "[2T#R]"
     ENDCASE
     vysledek = vysledek + ALLTRIM(SUBSTR(nazev, 4)) + " " + ALLT(rozsudek)
ENDSCAN 
vysledek = vysledek + m.crlf

DO uklid

IF .NOT. EMPT(m.i_seznam_souboru)
   SELECT soubory_zaloh
   REPLACE ALL            delka WITH ROUND(delka/1024/1024, 1)
   REPLACE FOR delka > 20 delka WITH ROUND(delka          , 0)
   REPLACE FOR delka > 99 delka WITH ROUND(delka          ,-1)
   INDEX ON nazev + STR(({^2044-12-12} - vytvoreno)) TAG nv
   o_naz = "\):*(/"
   SCAN
      IF m.o_naz # nazev
          o_naz = nazev
          vysledek = vysledek + m.crlf + "[2T#B] - - - - " + UPPER(ALLT(nazev)) + " - - - -" + m.crlf
      ENDIF 
      vysledek = vysledek + IIF(vytvoreno > DATE() - 10, "[1T#K]", "[1T#k]") + LEFT(ttoc(vytvoreno,3), 10) +  STR(delka, 11,1) + "MB   " + JUSTFNAME(ALLTRIM(adresar)) + m.crlf
   ENDSCAN
ENDIF

vysledek = vysledek + m.crlf + TRANSFORM(DISKSPACE(JUSTDRIVE(m.adresar_zaloh)) / 999999999, "Volne misto na " + JUSTDRIVE(m.adresar_zaloh)+ " 9999.9 GB") + m.crlf

COPY ALL TO .\sssouubory_zaloh2

CLOS DATA

vysledek = STRTR(m.vysledek, "  ", "&nbsp; ")
vysledek = STRTR(m.vysledek, "  ", "&nbsp; ")
vysledek = STRTR(m.vysledek, "  ", "&nbsp; ")
vysledek = STRTR(m.vysledek, "  ", "&nbsp; ")
vysledek = STRTR(m.vysledek, "  ", "&nbsp; ")


**** **** **** **** **** **** **** **** **** **** **** **** 
PROCEDURE uklid 

#DEFINE MAX_DELKA_PRO_CHECKSUM 999000111
SELECT nazev, delka, CNT(*) as pocet GROUP BY 1,2 FROM soubory_zaloh INTO CURSOR opakovane READWRITE
SCAN FOR pocet > 1 .and. delka < MAX_DELKA_PRO_CHECKSUM
    SCATTER MEMVAR 
    ? m.nazev, INT(delka/999)
    SELECT soubory_zaloh
    SCAN FOR nazev = m.nazev .and. delka = m.delka .and. vytvoreno < date() - 13
       REPLACE checksum WITH checksum(ALLTRIM(adresar))
    ENDSCAN 
ENDSCAN 

SELECT soubory_zaloh
REPLACE FOR EMPTY(checksum ) checksum WITH "___" + ALLTRIM(STR(RECNO()))
REPLACE ALL co_s_tim WITH "SMAZAT - chksum"
INDEX ON nazev + checksum TAG nc UNIQUE 
REPLACE ALL co_s_tim WITH ""

INDEX ON nazev + DTOS(vytvoreno) TAG nv FOR EMPTY(co_s_tim)
o_nazev = "\):*(/"
SCAN
    IF nazev = m.o_nazev
        REPLACE pocet_dni WITH vytvoreno - o_vytvoreno
    ELSE
        o_nazev = nazev
        REPLACE pocet_dni WITH 99
    ENDIF 
    o_vytvoreno = vytvoreno
ENDSCAN 

SELECT disti nazev FROM soubory_zaloh INTO CURSOR nazvy
SCAN
    SCATTER MEMVAR 
    SELECT soubory_zaloh
    SET ORDER TO 
    SET FILTER TO 
    LOCATE FOR nazev = m.nazev .and. pocet_dni < (DATE() - vytvoreno) / 11 .and. EMPTY(co_s_tim)
    IF FOUND()
        REPLACE co_s_tim WITH "SMAZAT"
    ENDIF   
ENDSCAN 

SELECT soubory_zaloh
SET FILTER TO 
INDEX ON nazev + DTOS(vytvoreno) TAG nv
SCAN FOR "SMAZAT" $ co_s_tim
    TRY 
        DELETE FILE (ALLTRIM(adresar))
    CATCH
    ENDTRY 
ENDSCAN 


**** **** **** **** **** **** **** **** **** **** **** **** 
FUNCTION checksum(filename)
fh = FOPEN(m.filename, 0)
IF fh > 0
    chs = ""
    DO WHILE .not. FEOF(fh)
        chs = m.chs + SYS(2007, FREAD(fh, 65432), 0, 1)
    ENDDO 
    FCLOSE(fh)
ELSE
    chs = filename
ENDIF 
RETURN SYS(2007, m.chs, 0, 1)


**** **** **** **** **** **** **** **** **** **** **** **** 
FUNCTION delka2stars(delka)
RETURN IIF(delka<266, "", REPLICATE("*", delka/188))


**** **** **** **** **** **** **** **** **** **** **** **** 
PROCEDURE  priprav_seznam_souboru
do jedenadresar with m.adresar_zaloh

sele soubory_zaloh
do while .t.
  locate for "D" $ atrib .and. delka = 0
  if found()
    repl delka with -111
    do jedenadresar with allt(adresar) + allt(nazev) + "\"
  else
    exit
  endif
enddo

DELETE FOR ATC("\jlv", adresar) + ATC("jlv-", nazev) + ATC("az-", nazev) > 0

DELETE FOR ATC("\archiv", adresar) > 0
DELETE FOR ATC("\stc"   , adresar) > 0

DELETE FOR atrib = "D"
DELETE FOR ATC(".zip  ", nazev) + ATC(".7z  ", nazev) + ATC(".pgdump  ", nazev) = 0
DELETE FOR vytvoreno < DATE() - 15
DELETE FOR .not. ("_20" $ nazev .or. "-20" $ nazev)
REPLACE ALL nazev WITH ALLTRIM(adresar) + nazev, adresar WITH nazev

SCAN 
    dat_v = RIGHT(JUSTSTEM(adresar), 10)
    TRY 
        REPLACE vytvoreno WITH DATE(VAL(LEFT(dat_v, 4)), VAL(SUBSTR(dat_v, 6, 2)), VAL(RIGHT(dat_v, 2)))
    CATCH 
    ENDTRY 
    repl pocet_dni with date() - vytvoreno
ENDSCAN

SCAN FOR ATC(".pgdump  ", nazev) = 0 
    IF SUBSTR(adresar, RAT(".", adresar)-1, 1) > "9"
        REPLACE adresar WITH LEFT(adresar, RAT(".", adresar)-1) + "_99." + JUSTEXT(adresar), nazev WITH LEFT(adresar,  RAT("_", adresar)-1)
    ENDIF 
ENDSCAN

SCAN
    DO CASE
    CASE RAT("_20", nazev) > 1
        REPLACE nazev WITH LEFT(nazev, RAT("_20", nazev)-1)
    CASE AT("-20", nazev) > 1
        REPLACE nazev WITH LEFT(nazev,  AT("-20", nazev)-1)
    ENDCASE
ENDSCAN 


**** **** **** **** **** **** **** **** **** **** **** **** 
proc jedenadresar
param adr
pocet = adir(qqq, m.adr + "*.*", "D")
for ii = 1 to m.pocet
  if left(qqq(ii, 1), 1) # "." .and. ATC("__", qqq(ii, 1)) = 0
     insert into soubory_zaloh (adresar, nazev, atrib, delka, vytvoreno) ;
        value (lowe(m.adr), lowe(qqq(ii, 1)), iif("D" $ qqq(ii, 5), "D", ""), qqq(ii, 2), qqq(ii, 3))
  endif
endfor
