Data de criação de arquivo no servidor - Fuso horário

Foto de Anderson

Categoria: 

A data e hora de um arquivo no servidor pode ser lida com as funções de FTP usando basicamente a TIpClientFtp(). Todavia, os servidores da web usam a hora universal UTC(link is external) 0 (Coordinated Universal Time). Daí é preciso converter a hora da coordenada 0 para a coordenada -3 que é a do Brasil para se obter a data e hora correta em nosso fuso horário. Em [x]Harbour, xBase, usamos a função SECS() que transforma a hora em segundos e a função TSTRING() que transforma de volta para hora.

Portanto, se você tentar comparar a hora do arquivo local com a do servidor que você acabou de fazer upload nunca dará igual sem que você faça a conversão do fuso horário na hora de baixá-lo.

Para obter a lista de arquivos no servidor você usará o método :listFiles() que funciona semelhante à nossa velha e conhecida função DIRECTORY() retornando uma matriz multidimensional com a lista de arquivos.

O problema dessa belezinha de método é que só vem a hora e minuto HH:MM, uma string de 5 caracteres, ao invés de vir completo com os segundos também, string com 8 caracteres HH:MM:SS. Ao menos no meu computador com o meu servidor foi assim. Daí precisei fazer ajustes para mitigar a diferença.

Precisei criar um objeto TURL() primeiramente para usar com o objeto TIpClientFtp() visto que meu nome de usuário das credenciais FTP contém um arroba ("@"), daí deu problema usando direto nela.

Essa rotina abaixo foi tirada de um sistema meu, portanto usa outras funções personalizadas e vai dar erro de "função não existe" se você tentar compilar, mas servirá para fins didáticos e poderá ser aproveitada perfeitamente em outros casos com as devidas substituições.

O exemplo que tenho no manual do xHarbour da função que mostra a barra de progresso de upload e download não funciona porque o terceiro parâmetro não dá o tamanho do arquivo, então temos que obter essa informação para passar para a função.

No exemplo abaixo eu quero saber se a data do arquivo manual.pdf no servidor é mais recente da que eu tenho localmente no computador que roda o sistema. Se for eu baixo.

Sem mais apresentações, vamos lá!

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
cMANUAL := "manual.pdf" // NOME DO ARQUIVO PARA BAIXAR SE FOR MAIS NOVO
IF FILE(cMANUAL)
    MSGRODA("Verificando se o manual existente é o mais recente...", "W+/BG")
     
    // VERIFICA SE HÁ MANUAL MAIS RECENTE
    // FTP CREDENTIALS
    oURL := TUrl():new()
    oUrl:cProto    := "ftp"
    oUrl:cUserid   := "seu nome de usuário FTP"  // altere
    oUrl:cPassword := "sua senha do FTP"         // altere
    oUrl:cServer   := "seu servidor"             // altere
    oUrl:nPort     := 21           
     
    MSGRODA("Abrindo conexão FTP...", "W+/BG"
    oFTP := TIpClientFtp():new( oURL ) // ABRE CONEXÃO FTP     
     
    IF oFTP:OPEN()     
        dHELP1 := dHELP2 := hHELP1 := hHELP2 := ""
        tHELP2 := 0
         
        // DATA E HORA DO ARQUIVO LOCAL
        aLOCAL := DIRECTORY("*.PDF")
        X := ASCAN(aLOCAL, {|A| UPPER(A[1]) == UPPER(cMANUAL)})
        IF X>0
            dHELP1 := aLOCAL[X][3]   // DATA DO ARQUIVO
            hHELP1 := aLOCAL[X][4]   // HORA DO ARQUIVO hh:mm:ss
            nSECS1 := SECS( hHELP1 ) // HORÁRIO EM SEGUNDOS
        ENDIF
         
        // DATA, HORA E TAMANHO DO ARQUIVO NA NUVEM
        MSGRODA("Acessando pasta remota...", "W+/BG")  
        oFTP:CWD("diretório onde estão os aquivos")    // altere
 
        MSGRODA("Obtendo lista de arquivos...", "W+/BG")   
        aNUVEM := oFTP:listFiles()     
        X := ASCAN(aNUVEM, {|A| UPPER(A[1]) == UPPER(cMANUAL)})
        IF X>0
           tHELP2 := aNUVEM[X][2]  // TAMANHO DO ARQUIVO
           oFTP:exGauge := {|nSENT, nTOTAL, oFTP| FtpProgress(nSENT, nTOTAL, oFTP, tHELP2) } // BARRA DE PROGRESSO CORRIGIDA QUE FUNCIONA
           dHELP2 := aNUVEM[X][3]  // DATA DO ARQUIVO
           hHELP2 := aNUVEM[X][4]  // HORA DO ARQUIVO hh:mm
           // EQUIPARAR HORAS
           hHELP1 := LEFT(hHELP1, LEN(hHELP2) ) // SE REMOTO HH:MM ENTÃO LOCAL HH:MM
           // Converter fuso horário UTC 0 para -3
           nSECS2 := SECS( hHELP2 )
           nUTC3  := (3*3600)   //  3h
           nSECS2 -= nUTC3      // -3h
           IF nSECS2 >= 0
                hHELP2 := TSTRING( nSECS2 )       // TRANSFORMA EM HORA
           ELSE
                // MADRUGADA DO DIA ANTERIOR, VOLTA 1 DIA
                dHELP2 -= 1                          // VOLTA 1 DIA
                hHELP2 := TSTRING( 86400 + nSECS2 )  // TRANSFORMA EM HORA NA FORMA CORRETA, NESSE CASO
                nSECS2 := SECS( hHELP2 )             // ATUALIZA nSECS2
           ENDIF          
        ENDIF
         
        nLAG := ABS( nSECS2 - nSECS1 )
        IF (nLAG/60) < 2 // TOLERÂNCIA DE LAG: 2min
            // DIFERENÇA IRRELEVANTE, ZERA A DIFERENÇA, CONSIDERA IGUAL.
            nSECS1 := nSECS2
        ENDIF
         
        IF dHELP1 < dHELP2 .OR. (dHELP1 == dHELP2 .AND. nSECS1 < nSECS2 )
            nBAIXA := ALERT("Há uma nova versão do manual, baixar agora?", {"Sim", "Não"})
            IF nBAIXA = 1
                MSGRODA("Iniciando download...", "W+/BG")  
                IF oFTP:downloadFile( cMANUAL ) // MÉTODO PARA FAZER O DOWNLOAD DO ARQUIVO
                    MSGRODA("Arquivo baixado com sucesso!", "W+/BG")
                ELSE
                    MSGRODA(oFtp:lastErrorMessage(), "W+/BG")
                ENDIF
            ENDIF
        ELSE
            MSGRODA("Você tem o manual mais recente!", "W+/BG")
        ENDIF
    ELSE
        MSGRODA(oFtp:lastErrorMessage(), "W+/BG")
    ENDIF
     
   // HELP EXISTE
   MSGRODA("Abrindo o manual no leitor padrão de PDF...", "W+/BG")
   RUN MANUAL.PDF
ENDIF  

Agora a função de progresso readequada:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// Displays a progress bar during file upload/download
FUNCTION FtpProgress( nSent, nFIM, oFtp, nSIZE )
  LOCAL cProgress
  LOCAL nRow := Row(), nCol := Col()
 
  cFILEDOWN := "Baixando "+ALLTRIM(oFtp:oUrl:cFile)+": "
  nMAXCOL := MAXCOL() - LEN(cFILEDOWN)
  cVAZIA    := Replicate( Chr(177), nMAXCOL )
  cProgress := Replicate( Chr(219), Int( nMAXCOL*nSent/nSIZE ) ) 
  cBAIXANDO := cFILEDOWN + cPROGRESS
   
  @ MAXROW(),00 SAY cFILEDOWN + cVAZIA COLOR "W+/BG"
  @ MAXROW(),00 SAY cBAIXANDO          COLOR "W+/BG"
   
  IF nSENT = nSIZE
    @ MAXROW(),00 SAY cFILEDOWN + Replicate( Chr(219), nMAXCOL )  COLOR "W+/BG" // só pra certificar
  ENDIF
 
  SetPos( nRow, nCol )
RETURN .T.

Observe que o parâmetro nFIM é o que deveria ter o tamanho do arquivo, mas sempre é -1, por isso não funcionava. Daí, damos um jeito de obter o tamanho do arquivo e passar para a função no parâmetro nSIZE. Tudo certo!

Total votes: 0