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 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á!

 

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:

// 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