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!
Comentários recentes