Exemplo de uso de HBCURL.LIB para xHarbour?

Projeto [x]Harbour - Compilador de código aberto compatível com o Clipper.

Moderador: Moderadores

Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por Kapiaba »

Bom dia, Alguém tem um Exemplo de uso de HBCURL.LIB para xHarbour?

Obg. abs.

Regards, saludos.
Avatar do usuário
Itamar M. Lins Jr.
Administrador
Administrador
Mensagens: 7928
Registrado em: 30 Mai 2007 11:31
Localização: Ilheus Bahia
Curtiu: 1 vez

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por Itamar M. Lins Jr. »

Olá!
E como é que faz a hbcurl sem MT ?
Os exemplos que tem no Harbour é com MT.
Já corrigiram o MT no xHarbour ?

Saudações,
Itamar M. Lins Jr.
Saudações,
Itamar M. Lins Jr.
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por sygecom »

Fala Kapiaba, tudo certo por ai ?

Meu colega João (teu chara) fez uma classe, vou postar aqui ficou show e fácil de usar.

Classe:

Código: Selecionar todos


#include 'hbclass.ch'
#include "hbcurl.ch"

#IfnDef __XHARBOUR__
   #include "hbcompat.ch"
#endif

#pragma /w2
#pragma /es2

CLASS oSyg_curl

/* $*AUTOR*$
      João Alpande
   $*CATEGORIA*$
      WEBSERVICE
   $*SUB-CATEGORIA*$
      WEBSERVICE
   $*PARAMETROS*$
      NÃO RECEBE
   $*RETORNO*$
      DEFINIÇÃO DA CLASSE oSyg_curl
   $*DESCRICAO*$
     Classe para uso da biblioteca libcurl 
   $*HISTORICO*$
      CRIAÇÃO: 05/12/2022
   $*EXEMPLOS*$
      oServerWS:=oSyg_curl():New()
   $*FIM*$
*/   
      DATA hCurl
      DATA nRetCurl            INIT 0       // CURLE_OK(0) significa que tudo estava OK, diferente de zero significa que ocorreu um erro
      DATA nHttpcode           INIT 0       // último código de resposta
      DATA cRetorno            INIT ''      // Mensagem de Retorno
      DATA cUrl                INIT ''      // URL
      DATA cHttpReq            INIT 'POST'  // método da requisição(POST, GET, DELETE, PUT)
      DATA aHeader             INIT {}      // array dos Headers
      DATA cEmailFrom          INIT ''      // E-mail From
      DATA aEmailTo            INIT {}      // array dos e-mails para oonde vai enviar
      DATA aEmailcc            INIT {}      // array dos e-mails que vai enviar como cc
      DATA aAnexos             INIT {}      // array dos Anexos que vai enviar no e-mail
      DATA cAssunto            INIT ''      // Assunto do Email
      DATA cMensagem           INIT ''      // Mensagem do Email
      DATA cJsonorXml          INIT ''
      DATA cCertFilePub        INIT ''
      DATA cCertPass           INIT ''
      DATA cCertFilePriv       INIT ''  
      DATA lAssinaturaDigital  INIT .F.     // .T. = vai enviar  cCertFilePub, cCertPass, cCertFilePriv 
      DATA nFollowlocation     INIT 0       //  0  = Desativado 1=siga redirecionamentos HTTP 3xx
      DATA nVerifypeer         INIT 0       //  0  = Desabilitando a verificação de mesmo nível SSL       
      DATA nTimeout            INIT 0       /* Tempo máximo em segundos que você permite que a operação de 
                                               transferência libcurl execute o temmpo limite padrão é 0 (zero), 
                                               o que significa que ele nunca expira durante a transferência.  */
      DATA nConnectTimeout     INIT 60      // Tempo limite para a fase de conexão - 60 segundos
      DATA lVerbose            INIT .F.     // .T. = Mostra informações detalhadas, serão enviadas para stderr,
                                            //       ou o fluxo definido comCURLOPT_STDERR
      DATA lInfHeader          INIT .F.     // .T. = Retorna o cabeçalho de resposta
      DATA lJsonDecode         INIT .F.     // .T. = Decodifica a resposta em um objeto JSON  
      DATA lMostraMsgRet       INIT .T.     // .T. = Mostra mensagem de Retorno     
      DATA hResposta           INIT Hash()  // Hash da resposta

      DATA cProxyUrl           INIT ''  
      DATA nProxyPort          INIT 0
      DATA cProxyUser          INIT ''  
      DATA cProxyPass          INIT ''
      DATA cUrlApiEmail        INIT 'http://email.seusitecomapi.com.br'  
       
      DATA bCodeProgress        

      METHOD New() CONSTRUCTOR
      METHOD SendHttp()   
      METHOD SendMailSendGrid()    
      METHOD SendTokenApiEmail(cToken)
      METHOD SendMailApi()       
      METHOD DownloadFile(cArquivo,cSalvaOnde)
      METHOD MsgStatusHttp() 
      METHOD Reset()  
      METHOD End()

EndClass

*****************************
METHOD New() CLASS oSyg_curl
*****************************

::hCurl := curl_easy_init()
::hResposta := Hash()

RETURN self

*******************************
METHOD Reset() CLASS oSyg_curl
*******************************   
                     
    curl_easy_reset( ::hCurl )
 
RETURN NIL


*****************************
METHOD End() CLASS oSyg_curl
*****************************
  
IF !EMPTY(::hCurl)    
   curl_easy_cleanup( ::hCurl )
ENDIF   
::hCurl := Nil  

#IfDef _XHARBOUR_
   hb_gcAll( .t. )
#endif
          
RETURN NIL
 
 

 
****************************************
METHOD SendHttp() Class oSyg_curl
****************************************
LOCAL lRET:=.T.

IF EMPTY(::hCurl)
   IF ::lMostraMsgRet
      ShowMsg('Não INICIOU a classe da libcurl.dll corretamente.')
   ENDIF   
   RETURN .F.
ENDIF

IF EMPTY(::cUrl) 
   IF ::lMostraMsgRet
      ShowMsg('Não enviou a Url para a classe.')
   ENDIF   
   RETURN .F.
ENDIF 
IF EMPTY(::cHttpReq)
   IF ::lMostraMsgRet
      ShowMsg('Não enviou o método da requisição(POST, GET, DELETE, PUT) para a classe.')
   ENDIF   
   RETURN .F.
ENDIF 

/*não retirar este código comentado , podemos usar para fazer algum teste
    showmsg_edit('URL : ' + ::cUrl     +hb_osnewline()+;
                 'METODO:'+ ::cHttpReq +hb_osnewline()+;
                 IF(!EMPTY(::cJsonorXml), 'JSON/XML: '+hb_osnewline()+ ::cJsonorXml   ,'' ) )
*/
   
IF ::cHttpReq = 'POST'
   IF ::aHeader = Nil 
      AADD(::aHeader,"Content-Type: application/json")
   ELSEIF LEN(::aHeader) = 0
      AADD(::aHeader,"Content-Type: application/json")  
   ENDIF
ENDIF

curl_easy_setopt(::hCurl, HB_CURLOPT_URL, ::cUrl)
curl_easy_setopt(::hCurl, HB_CURLOPT_FOLLOWLOCATION, ::nFollowlocation)
curl_easy_setopt(::hCurl, HB_CURLOPT_SSL_VERIFYPEER, ::nVerifypeer )

IF ::lAssinaturaDigital
   curl_easy_setopt(::hCurl, HB_CURLOPT_SSLCERT,   ::cCertFilePub)
   curl_easy_setopt(::hCurl, HB_CURLOPT_KEYPASSWD, ::cCertPass)
   curl_easy_setopt(::hCurl, HB_CURLOPT_SSLKEY,    ::cCertFilePriv)
ENDIF

IF !EMPTY(::cProxyUrl)    
   curl_easy_setopt(::hCurl, HB_CURLOPT_PROXY , ::cProxyUrl+":"+ALLTRIM(STR(::nProxyPort))) 
   IF !EMPTY(::cProxyUser)
      curl_easy_setopt(::hCurl, HB_CURLOPT_PROXYUSERPWD , ::cProxyUser+":"+ ::cProxyPass )
   ENDIF   
ENDIF

curl_easy_setopt(::hCurl, HB_CURLOPT_TIMEOUT, ::nTimeout )
curl_easy_setopt(::hCurl, HB_CURLOPT_CONNECTTIMEOUT, ::nConnectTimeout ) 
curl_easy_setopt(::hCurl, HB_CURLOPT_VERBOSE, ::lVerbose ) 
curl_easy_setopt(::hCurl, HB_CURLOPT_HEADER, ::lInfHeader ) 
curl_easy_setopt(::hCurl, HB_CURLOPT_CUSTOMREQUEST , ::cHttpReq)  
curl_easy_setopt(::hCurl, HB_CURLOPT_POSTFIELDS, ::cJsonorXml)
curl_easy_setopt(::hCurl, HB_CURLOPT_DL_BUFF_SETUP )
curl_easy_setopt(::hCurl, HB_CURLOPT_HTTPHEADER, ::aHeader )
curl_easy_setopt(::hCurl, HB_CURLOPT_DL_BUFF_SETUP )

::nRetCurl := curl_easy_perform(::hCurl)
::nHttpcode:= curl_easy_getinfo( ::hCurl, HB_CURLINFO_RESPONSE_CODE )
::cRetorno := curl_easy_dl_buff_get( ::hCurl )

/*não retirar este código comentado , podemos usar para fazer algum teste
   showmsg_edit('RETCURL : ' + ALLTRIM(STR(::nRetCurl))   +hb_osnewline()+;
                'HTTPCOD : ' + ALLTRIM(STR(::nHttpcode))  +hb_osnewline()+;
                'RESPOSTA: ' + ALLTRIM(::cRetorno)  )
*/

IF ::nRetCurl = HB_CURLE_OK  // 0= OK
   IF ::nHttpcode >= 200 .AND. ::nHttpcode < 300  // Sucesso
      lRET:=.T.   
   ELSE 
      lRET:=.F. 
      IF ::lMostraMsgRet
         ::MsgStatusHttp() 
      ENDIF
   ENDIF 
ELSE 
   lRET:=.F. 
   /*
   Isso não pode está na classe, se precisar tem que ler o ::cRetorno onde está chamando a classe - Leonardo Machado - 13/06/2023
   IF ::lMostraMsgRet
      Showmsg_Edit( ::cRetorno ,'Erro Inesperado' )  
   ENDIF  
   */
ENDIF

IF lRET .AND. ::lJsonDecode 
   hb_jsondecode( ::cRetorno, @::hResposta ) 
ENDIF

RETURN(lRET) 

*****************************************
METHOD SendMailSendGrid() Class oSyg_curl
*****************************************
LOCAL lRET:=.T., nI:=0, cTipo:='text/plain', cExtensao:='',cAnexo:=''

IF EMPTY(::cEmailFrom) 
   ::cEmailFrom:= 'no-reply@meusite.com.br'
ENDIF 

IF LEN(::aEmailTo) = 0
   IF ::lMostraMsgRet
      ShowMsg('Não enviou o e-mail para onde vai enviar.')
   ENDIF   
   RETURN .F.
ENDIF 

IF EMPTY(::cAssunto)
   IF ::lMostraMsgRet
      ShowMsg('Não enviou o assunto do e-mail.')
   ENDIF   
   RETURN .F.
ENDIF 

IF EMPTY(::cMensagem)
   IF ::lMostraMsgRet
      ShowMsg('Não enviou o mensagem do e-mail.')
   ENDIF   
   RETURN .F.
ENDIF 

/*não retirar este código comentado , podemos usar para fazer algum teste
    showmsg_edit('URL : ' + ::cUrl     +hb_osnewline()+;
                 'METODO:'+ ::cHttpReq +hb_osnewline()+;
                 IF(!EMPTY(::cJsonorXml), 'JSON/XML: '+hb_osnewline()+ ::cJsonorXml   , ) )
*/
::cJsonorXml:= ' { "personalizations": '+ HB_OsNewLine()+;
               ' [ '+ HB_OsNewLine()+;  
               ' {"to": ['+ HB_OsNewLine()

FOR nI:=1 TO LEN(::aEmailTo)
    IF !EMPTY(::aEmailTo[nI,1])
       ::cJsonorXml+= '{"email": "' + ALLTRIM(::aEmailTo[nI,1]) + '"} ' + IF(LEN(::aEmailTo) > nI , ',', '') + HB_OsNewLine()         
    ENDIF   
NEXT
::cJsonorXml+= '] '

IF LEN(::aEmailcc) > 0
   ::cJsonorXml+=', "cc": ['
   FOR nI:=1 TO LEN(::aEmailcc)
       IF !EMPTY(::aEmailcc[nI,1])
          ::cJsonorXml+= '{"email": "' + ALLTRIM(::aEmailcc[nI,1]) + '"} ' + IF(LEN(::aEmailcc) > nI , ',', '') + HB_OsNewLine()         
       ENDIF   
   NEXT 
   ::cJsonorXml+= '] '
ENDIF


::cMensagem:= STRTRAN(::cMensagem,'\', '\\')
::cMensagem:= STRTRAN(::cMensagem,'"', "'")
::cMensagem:= STRTRAN(::cMensagem,CHR(13), ' ')
::cMensagem:= STRTRAN(::cMensagem,CHR(10), ' \n ')
::cMensagem:= hb_StrToUTF8( ::cMensagem) 

::cJsonorXml+= ' }], '+ HB_OsNewLine()
::cJsonorXml+=' "from": {"email": "'+ ALLTRIM(::cEmailFrom) + '"}, ' + HB_OsNewLine()
::cJsonorXml+=' "subject": "'+ hb_StrToUTF8(ALLTRIM(::cAssunto)) + '", '+ HB_OsNewLine()
::cJsonorXml+=' "content": [{"type": "text/plain", "value": "' + ALLTRIM(::cMensagem) + '"} ]  ' + HB_OsNewLine()

//se tem anexos
IF LEN(::aAnexos) > 0
   ::cJsonorXml+= ', "attachments": [ ' + HB_OsNewLine()
   FOR nI:=1 TO LEN(::aAnexos)
       IF !EMPTY(::aAnexos[nI,2])
          cAnexo:= MemoRead(::aAnexos[nI,2])
          cAnexo:= SYG_BASE64ENCODE(cAnexo)
          cAnexo:= Syg_Limpa( ALLTRIM( cAnexo ) )
     
          cExtensao:= UPPER(Subs(::aAnexos[nI,2],RAT(".",::aAnexos[nI,2])+1))
          IF ALLTRIM(cExtensao) = 'PDF'
             cTipo:= 'application/pdf'
          ELSEIF ALLTRIM(cExtensao) = 'BMP' .OR. ALLTRIM(cExtensao) = 'JPEG' .OR. ;
                 ALLTRIM(cExtensao) = 'JPG' .OR. ALLTRIM(cExtensao) = 'PNG' .OR. ;
                 ALLTRIM(cExtensao) = 'JPG' .OR. ALLTRIM(cExtensao) = 'GIF'
             cTipo:= 'image/'+LOWER(ALLTRIM(cExtensao))           
          ELSEIF ALLTRIM(cExtensao) = 'CSV' .OR. ALLTRIM(cExtensao) = 'HTML' ;
            .OR. ALLTRIM(cExtensao) = 'HTM' .OR. ALLTRIM(cExtensao) = 'CSS'
             cTipo:= 'text/'+LOWER(ALLTRIM(cExtensao)) 
          ELSEIF ALLTRIM(cExtensao) = 'ICO'    
             cTipo:= 'image/image/vnd.microsoft.icon'
          ELSEIF ALLTRIM(cExtensao) = 'XML'  
              cTipo:= 'application/xml'
          ELSEIF ALLTRIM(cExtensao) = 'ZIP'  
           cTipo:= 'application/zip'     
          ELSEIF ALLTRIM(cExtensao) = 'RAR'  
              cTipo:= 'application/vnd.rar'                
          ELSEIF ALLTRIM(cExtensao) = 'XLS' 
              cTipo:= 'application/vnd.ms-excel'         
          ELSEIF ALLTRIM(cExtensao) = 'XLSX'  
              cTipo:= 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
          ELSEIF ALLTRIM(cExtensao) = 'ODS'   
              cTipo:= 'application/vnd.oasis.opendocument.spreadsheet'
          ELSE 
              cTipo:= 'text/plain'
          ENDIF
            
          ::cJsonorXml+= ' { "content": "'+ALLTRIM(cAnexo) +'",'   + HB_OsNewLine()
          ::cJsonorXml+= ' "type": "'+ ALLTRIM(cTipo) +'",'   + HB_OsNewLine()
          ::cJsonorXml+= ' "filename": "' + ALLTRIM(::aAnexos[nI,1]) +'"'+HB_OsNewLine()
          ::cJsonorXml+= ' }  '+ IF(LEN(::aAnexos) > nI , ',', '') + HB_OsNewLine() 
      ENDIF
   NEXT 
   ::cJsonorXml+= ' ] '  + HB_OsNewLine()
ENDIF
::cJsonorXml+='}'
//hwg_WriteLog(::cJsonorXml, 'testecurl.txt' )

IF EMPTY(::cUrl) // se não envia a url do sendgrid usa a conta sendgrid da Sygecom
   ::cUrl := 'https://api.sendgrid.com/v3/mail/send'
   AADD(::aHeader,"Authorization: Bearer "+'aqui vai o token do sendgrid' )
ENDIF

AADD(::aHeader,"Content-Type: application/json")

curl_easy_setopt(::hCurl, HB_CURLOPT_URL, ::cUrl)
curl_easy_setopt(::hCurl, HB_CURLOPT_FOLLOWLOCATION, ::nFollowlocation)
curl_easy_setopt(::hCurl, HB_CURLOPT_SSL_VERIFYPEER, ::nVerifypeer )

IF !EMPTY(::cProxyUrl)    
   curl_easy_setopt(::hCurl, HB_CURLOPT_PROXY , ::cProxyUrl+":"+ALLTRIM(STR(::nProxyPort))) 
   IF !EMPTY(::cProxyUser)
      curl_easy_setopt(::hCurl, HB_CURLOPT_PROXYUSERPWD , ::cProxyUser+":"+::cProxyPass )
   ENDIF   
ENDIF

curl_easy_setopt(::hCurl, HB_CURLOPT_TIMEOUT, ::nTimeout )
curl_easy_setopt(::hCurl, HB_CURLOPT_CONNECTTIMEOUT, ::nConnectTimeout ) 
curl_easy_setopt(::hCurl, HB_CURLOPT_VERBOSE, ::lVerbose ) 
curl_easy_setopt(::hCurl, HB_CURLOPT_HEADER, ::lInfHeader ) 
curl_easy_setopt(::hCurl, HB_CURLOPT_CUSTOMREQUEST , ::cHttpReq)  
curl_easy_setopt(::hCurl, HB_CURLOPT_POSTFIELDS, ::cJsonorXml)
curl_easy_setopt(::hCurl, HB_CURLOPT_DL_BUFF_SETUP )
curl_easy_setopt(::hCurl, HB_CURLOPT_HTTPHEADER, ::aHeader )
curl_easy_setopt(::hCurl, HB_CURLOPT_DL_BUFF_SETUP )

::nRetCurl := curl_easy_perform(::hCurl)
::nHttpcode:= curl_easy_getinfo( ::hCurl, HB_CURLINFO_RESPONSE_CODE )
::cRetorno := curl_easy_dl_buff_get( ::hCurl )

/*não retirar este código comentado , podemos usar para fazer algum teste
   showmsg_edit('RETCURL : ' + ALLTRIM(STR(::nRetCurl))   +hb_osnewline()+;
                'HTTPCOD : ' + ALLTRIM(STR(::nHttpcode))  +hb_osnewline()+;
                'RESPOSTA: ' + ALLTRIM(::cRetorno)  )
*/

IF ::nRetCurl = HB_CURLE_OK  // 0= OK
   IF ::nHttpcode >= 200 .AND. ::nHttpcode < 300  // Sucesso
      lRET:=.T.    
      IF LEN(::aEmailTo)>0  
         FOR nI:=1 TO LEN(::aEmailTo)
            IF !EMPTY(::aEmailTo[nI,1])
               //GRAVALOG('ENVIADO E-MAIL PARA: ' + ::aEmailTo[nI,1] )
            ENDIF
         NEXT
      ENDIF
   ELSE 
      lRET:=.F. 
      IF ::lMostraMsgRet
         ::MsgStatusHttp() 
      ENDIF
   ENDIF 
ELSE 
   lRET:=.F. 
   
   /*
   Isso não pode está na classe, se precisar tem que ler o ::cRetorno onde está chamando a classe - Leonardo Machado - 13/06/2023
   IF ::lMostraMsgRet
      Showmsg_Edit( ::cRetorno ,'Erro Inesperado' )  
   ENDIF 
   */ 
ENDIF

IF lRET .AND. ::lJsonDecode 
   hb_jsondecode( ::cRetorno, @::hResposta ) 
ENDIF

RETURN(lRET) 

********************************************************
METHOD DownloadFile(cArquivo,cSalvaOnde) Class oSyg_curl
********************************************************
LOCAL lRet:=.F., cUrl

cArquivo   := IF(cArquivo=Nil, '',cArquivo)
cSalvaOnde := IF(cSalvaOnde=Nil, '',cSalvaOnde)

IF !EMPTY(cArquivo) .AND. !EMPTY(cSalvaOnde)
   IF !EMPTY( cUrl := curl_easy_init() )
      curl_easy_setopt( cUrl, HB_CURLOPT_SSL_VERIFYPEER, ::nVerifypeer )
      IF !EMPTY(::cProxyUrl)    
         curl_easy_setopt(::hCurl, HB_CURLOPT_PROXY , ::cProxyUrl+":"+ALLTRIM(STR(::nProxyPort))) 
         IF !EMPTY(::cProxyUser)
            curl_easy_setopt(::hCurl, HB_CURLOPT_PROXYUSERPWD , ::cProxyUser+":"+::cProxyPass )
         ENDIF   
      ENDIF
       
      curl_easy_setopt( cUrl, HB_CURLOPT_DOWNLOAD )   
      curl_easy_setopt( cUrl, HB_CURLOPT_URL, ::cUrl )
      curl_easy_setopt( curl, HB_CURLOPT_DL_FILE_SETUP,  cSalvaOnde )  
      IF !EMPTY(::bCodeProgress)
         curl_easy_setopt( curl, HB_CURLOPT_PROGRESSBLOCK, ::bCodeProgress )
      ENDIF   
      curl_easy_setopt( curl, HB_CURLOPT_NOPROGRESS, 0 ) 
      curl_easy_perform( curl )
      lRet:=.T.     
   ENDIF
ENDIF

RETURN(lRET) 

*****************************************
METHOD SendMailApi() Class oSyg_curl
*****************************************
LOCAL lRET:=.T., nI:=0, cTipo:='text/plain', cExtensao:='',cAnexo:='', cToken:='',  lMostraMsgRet_Old:=.F.

IF LEN(::aEmailTo) = 0
   IF ::lMostraMsgRet
      ShowMsg('Não enviou o e-mail para onde vai enviar.')
   ENDIF   
   RETURN .F.
ENDIF 
                                          
IF EMPTY(::cAssunto)
   IF ::lMostraMsgRet
      ShowMsg('Não enviou o assunto do e-mail.')
   ENDIF   
   RETURN .F.
ENDIF 

IF EMPTY(::cMensagem)
   IF ::lMostraMsgRet
      ShowMsg('Não enviou o mensagem do e-mail.')
   ENDIF   
   RETURN .F.
ENDIF 

//Obter Token
lMostraMsgRet_Old:= ::lMostraMsgRet
::lMostraMsgRet:= .F.
IF !::SendTokenApiEmail(@cToken) .OR. EMPTY(cToken)
   ::lMostraMsgRet:=lMostraMsgRet_Old 
   IF ::lMostraMsgRet
      ShowMsg('Não gerou corretamento o token do e-mail.')
   ENDIF  
   RETURN .F.
ENDIF
::lMostraMsgRet:=lMostraMsgRet_Old 

::New()

::cJsonorXml:= '{ "destinatario": ['+ HB_OsNewLine()

FOR nI:=1 TO LEN(::aEmailTo)
    IF !EMPTY(::aEmailTo[nI,1])
       ::cJsonorXml+= '"'+ALLTRIM(::aEmailTo[nI,1]) + '"' + IF(LEN(::aEmailTo) > nI , ','+ HB_OsNewLine(), '')          
    ENDIF   
NEXT
::cJsonorXml+= '], '  

::cJsonorXml+=' "assunto": "' +  hb_StrToUTF8(ALLTRIM(::cAssunto)) + '", '+ HB_OsNewLine()

IF LEN(::aEmailcc) > 0
   ::cJsonorXml+='"copiados": ['
   FOR nI:=1 TO LEN(::aEmailcc)
       IF !EMPTY(::aEmailcc[nI,1])
          ::cJsonorXml+=  '"'+ALLTRIM(::aEmailcc[nI,1])  + '"'+ IF(LEN(::aEmailcc) > nI , ','+ HB_OsNewLine(), '')          
       ENDIF   
   NEXT 
   ::cJsonorXml+= '], '  + HB_OsNewLine()
ENDIF

::cMensagem:= STRTRAN(::cMensagem,'\', '\\')
::cMensagem:= STRTRAN(::cMensagem,'"', "'")
::cMensagem:= STRTRAN(::cMensagem,CHR(13), ' ')
::cMensagem:= STRTRAN(::cMensagem,CHR(10), ' \n ')
::cMensagem:= ::cMensagem  

::cJsonorXml+=' "texto": "'+hb_StrToUTF8(ALLTRIM(::cMensagem)) + '" '+ HB_OsNewLine()

//se tem anexos
IF LEN(::aAnexos) > 0
       
   ::cJsonorXml+= ', "anexos": [ ' + HB_OsNewLine()
   FOR nI:=1 TO LEN(::aAnexos)
       IF !EMPTY(::aAnexos[nI,2])
          cAnexo:= MemoRead(::aAnexos[nI,2])
          cAnexo:= SYG_BASE64ENCODE(cAnexo)
          cAnexo:= Syg_Limpa( ALLTRIM( cAnexo ) )
     
          cExtensao:= UPPER(Subs(::aAnexos[nI,2],RAT(".",::aAnexos[nI,2])+1))
          IF ALLTRIM(cExtensao) = 'PDF'
             cTipo:= 'application/pdf'
          ELSEIF ALLTRIM(cExtensao) = 'BMP' .OR. ALLTRIM(cExtensao) = 'JPEG' .OR. ;
                 ALLTRIM(cExtensao) = 'JPG' .OR. ALLTRIM(cExtensao) = 'PNG' .OR. ;
                 ALLTRIM(cExtensao) = 'JPG' .OR. ALLTRIM(cExtensao) = 'GIF'
             cTipo:= 'image/'+LOWER(ALLTRIM(cExtensao))           
          ELSEIF ALLTRIM(cExtensao) = 'CSV' .OR. ALLTRIM(cExtensao) = 'HTML' ;
            .OR. ALLTRIM(cExtensao) = 'HTM' .OR. ALLTRIM(cExtensao) = 'CSS'
             cTipo:= 'text/'+LOWER(ALLTRIM(cExtensao)) 
          ELSEIF ALLTRIM(cExtensao) = 'ICO'    
             cTipo:= 'image/image/vnd.microsoft.icon'
          ELSEIF ALLTRIM(cExtensao) = 'XML'  
              cTipo:= 'application/xml'
          ELSEIF ALLTRIM(cExtensao) = 'ZIP'  
           cTipo:= 'application/zip'     
          ELSEIF ALLTRIM(cExtensao) = 'RAR'  
              cTipo:= 'application/vnd.rar'                
          ELSEIF ALLTRIM(cExtensao) = 'XLS' 
              cTipo:= 'application/vnd.ms-excel'         
          ELSEIF ALLTRIM(cExtensao) = 'XLSX'  
              cTipo:= 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' 
          ELSEIF ALLTRIM(cExtensao) = 'ODS'   
              cTipo:= 'application/vnd.oasis.opendocument.spreadsheet'
          ELSE 
              cTipo:= 'text/plain'
          ENDIF
          ::cJsonorXml+= ' { "base64": "'+ALLTRIM(cAnexo) +'",'   + HB_OsNewLine()
          ::cJsonorXml+= ' "formato": "'+ ALLTRIM(cTipo) +'",'   + HB_OsNewLine()
          ::cJsonorXml+= ' "filename": "' + ALLTRIM(::aAnexos[nI,1]) +'"'+HB_OsNewLine()
          ::cJsonorXml+= ' }  '+ IF(LEN(::aAnexos) > nI , ',', '') + HB_OsNewLine()           
      ENDIF
   NEXT 
   ::cJsonorXml+= ' ] '  + HB_OsNewLine()
   
ENDIF
::cJsonorXml+='}'
//hwg_WriteLog('JsonI: ' + ::cJsonorXml+  HB_OsNewLine() + Alltrim(::cUrlApiEmail)+'/sendEmail' + HB_OsNewLine() , 'testecurl.txt' )

::aHeader:={}
 
AADD(::aHeader,"Authorization: Bearer "+Alltrim(cToken) )
AADD(::aHeader,"Content-Type: application/json")
                                       
curl_easy_setopt(::hCurl, HB_CURLOPT_URL, Alltrim(::cUrlApiEmail)+'/sendEmail')
curl_easy_setopt(::hCurl, HB_CURLOPT_FOLLOWLOCATION, ::nFollowlocation)
curl_easy_setopt(::hCurl, HB_CURLOPT_SSL_VERIFYPEER, ::nVerifypeer )

IF !EMPTY(::cProxyUrl)    
   curl_easy_setopt(::hCurl, HB_CURLOPT_PROXY , ::cProxyUrl+":"+ALLTRIM(STR(::nProxyPort))) 
   IF !EMPTY(::cProxyUser)
      curl_easy_setopt(::hCurl, HB_CURLOPT_PROXYUSERPWD , ::cProxyUser+":"+::cProxyPass )
   ENDIF   
ENDIF

curl_easy_setopt(::hCurl, HB_CURLOPT_TIMEOUT, ::nTimeout )
curl_easy_setopt(::hCurl, HB_CURLOPT_CONNECTTIMEOUT, ::nConnectTimeout ) 
curl_easy_setopt(::hCurl, HB_CURLOPT_VERBOSE, ::lVerbose ) 
curl_easy_setopt(::hCurl, HB_CURLOPT_HEADER, ::lInfHeader ) 
curl_easy_setopt(::hCurl, HB_CURLOPT_CUSTOMREQUEST , 'POST')  
curl_easy_setopt(::hCurl, HB_CURLOPT_POSTFIELDS, Alltrim(::cJsonorXml))
curl_easy_setopt(::hCurl, HB_CURLOPT_DL_BUFF_SETUP )
curl_easy_setopt(::hCurl, HB_CURLOPT_HTTPHEADER, ::aHeader )
curl_easy_setopt(::hCurl, HB_CURLOPT_DL_BUFF_SETUP )

::nRetCurl := curl_easy_perform(::hCurl)
::nHttpcode:= curl_easy_getinfo( ::hCurl, HB_CURLINFO_RESPONSE_CODE )
::cRetorno := curl_easy_dl_buff_get( ::hCurl )

/*não retirar este código comentado , podemos usar para fazer algum teste
   showmsg_edit('RETCURL : ' + ALLTRIM(STR(::nRetCurl))   +hb_osnewline()+;
                'HTTPCOD : ' + ALLTRIM(STR(::nHttpcode))  +hb_osnewline()+;
                'RESPOSTA: ' + ALLTRIM(::cRetorno)  )
*/

IF ::nRetCurl = HB_CURLE_OK  // 0= OK
   IF ::nHttpcode >= 200 .AND. ::nHttpcode < 300  // Sucesso
      lRET:=.T.    
   ELSE 
      lRET:=.F. 
      IF ::lMostraMsgRet
         ::MsgStatusHttp() 
      ENDIF
   ENDIF 
ELSE 
   lRET:=.F.    
ENDIF

IF lRET .AND. ::lJsonDecode 
   hb_jsondecode( ::cRetorno, @::hResposta ) 
ENDIF

RETURN(lRET) 


******************************************************************
METHOD SendTokenApiEmail(cToken) Class oSyg_curl
*****************************************************************
LOCAL lRet:= .F.

::cUrl       := Alltrim(::cUrlApiEmail)+'/auth'
::cHttpReq   := 'POST'
::cJsonorXml := '{ "username": "nome_usuario", "password": "senha_do_usuario" }'
::lJsonDecode:= .T.

IF ::SendHttp()  // .T. deu certo 
   cToken  := ::hResposta["token"] 
   lRet:= .T.
ENDIF
::End() 
 
RETURN(lRET) 

********************************************
METHOD MsgStatusHttp() Class oSyg_curl
********************************************

LOCAL aMsgRetorno:={}, nScan:=0

AADD(aMsgRetorno, {300,'Mensagem de redirecionamento','A requisição tem mais de uma resposta possível. User-agent ou o user deve escolher uma delas.'+hb_osnewline() +; 
                                                      'Não há maneira padrão para escolher uma das respostas.'})
AADD(aMsgRetorno, {301,'Mensagem de redirecionamento','Esse código de resposta significa que a URI do recurso requerido mudou. Provavelmente, a nova URI será especificada na resposta.'})
AADD(aMsgRetorno, {302,'Mensagem de redirecionamento','Esse código de resposta significa que a URI do recurso requerido foi mudada temporariamente.'+hb_osnewline() +; 
                                                       'Novas mudanças na URI poderão ser feitas no futuro. Portanto, a mesma URI deve ser usada pelo cliente em requisições futuras.'})
AADD(aMsgRetorno, {303,'Mensagem de redirecionamento','O servidor manda essa resposta para instruir ao cliente buscar o recurso requisitado em outra URI com uma requisição GET.'})
AADD(aMsgRetorno, {304,'Mensagem de redirecionamento','Essa resposta é usada para questões de cache. Diz ao cliente que a resposta não foi modificada. '+hb_osnewline() +; 
                                                      'Portanto, o cliente pode usar a mesma versão em cache da resposta.'} )
AADD(aMsgRetorno, {305,'Mensagem de redirecionamento','Foi definida em uma versão anterior da especificação HTTP para indicar que uma resposta deve ser acessada por um proxy.' +hb_osnewline() +; 
                                                      'Foi depreciada por questões de segurança em respeito a configuração em banda de um proxy.'})
AADD(aMsgRetorno, {306,'Mensagem de redirecionamento','Esse código de resposta não é mais utilizado, encontra-se reservado. Foi usado numa versão anterior da especificação HTTP 1.1.'})
AADD(aMsgRetorno, {307,'Mensagem de redirecionamento','O servidor mandou essa resposta direcionando o cliente a buscar o recurso requisitado em outra URI com o mesmo método que foi '+hb_osnewline() +; 
                                                      'utilizado na requisição original. Tem a mesma semântica do código 302 Found, com a exceção de que o user-agent não deve mudar '+hb_osnewline() +; 
                                                      'o método HTTP utilizado: se um POST foi utilizado na primeira requisição, um POST deve ser utilizado na segunda.'})
AADD(aMsgRetorno, {308,'Mensagem de redirecionamento','Esse código significa que o recurso agora está permanentemente localizado em outra URI, especificada pelo cabeçalho de resposta Location. '+hb_osnewline() +; 
                                                      'Tem a mesma semântica do código de resposta HTTP 301 Moved Permanently com a exceção de que o user-agent não deve mudar '+hb_osnewline() +; 
                                                      'o método HTTP utilizado: se um POST foi utilizado na primeira requisição, um POST deve ser utilizado na segunda.'})

AADD(aMsgRetorno, {400,'Resposta de erro do Cliente','Essa resposta significa que o servidor não entendeu a requisição pois está com uma sintaxe inválida.'})
AADD(aMsgRetorno, {401,'Resposta de erro do Cliente','Embora o padrão HTTP especifique "unauthorized", semanticamente, essa resposta significa "unauthenticated". '+hb_osnewline() +; 
                                                     'ou seja, o cliente deve se autenticar para obter a resposta solicitada.'})
AADD(aMsgRetorno, {402,'Resposta de erro do Cliente','Este código de resposta está reservado para uso futuro. O objetivo inicial da criação deste código era usá-lo'+hb_osnewline() +; 
                                                     ' para sistemas digitais de pagamento porém ele não está sendo usado atualmente.'})
AADD(aMsgRetorno, {403,'Resposta de erro do Cliente','O cliente não tem direitos de acesso ao conteúdo portanto o servidor está rejeitando dar a resposta. '+hb_osnewline() +; 
                                                     'Diferente do código 401, aqui a identidade do cliente é conhecida.'})
AADD(aMsgRetorno, {404,'Resposta de erro do Cliente','O servidor não pode encontrar o recurso solicitado. Este código de resposta talvez seja o mais famoso devido '+hb_osnewline() +;
                                                     'à frequência com que acontece na web.'})
AADD(aMsgRetorno, {405,'Resposta de erro do Cliente','O método de solicitação é conhecido pelo servidor, mas foi desativado e não pode ser usado.'})
AADD(aMsgRetorno, {406,'Resposta de erro do Cliente','Essa resposta é enviada quando o servidor da Web após realizar a negociação de conteúdo orientada pelo servidor, '+hb_osnewline() +; 
                                                     'não encontra nenhum conteúdo seguindo os critérios fornecidos pelo agente do usuário.'})
AADD(aMsgRetorno, {407,'Resposta de erro do Cliente','Semelhante ao 401 porem é necessário que a autenticação seja feita por um proxy.'})
AADD(aMsgRetorno, {408,'Resposta de erro do Cliente','Esta resposta é enviada por alguns servidores em uma conexão ociosa, mesmo sem qualquer requisição prévia pelo cliente. '+hb_osnewline() +; 
                                                     'Ela significa que o servidor gostaria de derrubar esta conexão em desuso. Esta resposta é muito usada já que alguns navegadores, '+hb_osnewline() +; 
                                                     'como Chrome, Firefox 27+, ou IE9, usam mecanismos HTTP de pré-conexão para acelerar a navegação. '+hb_osnewline() +; 
                                                     'Note também que alguns servidores meramente derrubam a conexão sem enviar esta mensagem.'})
AADD(aMsgRetorno, {409,'Resposta de erro do Cliente','Esta resposta será enviada quando uma requisição conflitar com o estado atual do servidor.'})
AADD(aMsgRetorno, {410,'Resposta de erro do Cliente','Esta resposta será enviada quando o conteúdo requisitado foi permanentemente deletado do servidor, sem nenhum endereço de redirecionamento.'+hb_osnewline() +; 
                                                     'É esperado que clientes removam seus caches e links para o recurso. A especificação HTTP espera que este código de status seja usado para '+hb_osnewline() +; 
                                                     '"serviços promocionais de tempo limitado". APIs não devem se sentir obrigadas a indicar que recursos foram removidos com este código de status.'})
AADD(aMsgRetorno, {411,'Resposta de erro do Cliente','O servidor rejeitou a requisição porque o campo Content-Length do cabeçalho não está definido e o servidor o requer.'})
AADD(aMsgRetorno, {412,'Resposta de erro do Cliente','O cliente indicou nos seus cabeçalhos pré-condições que o servidor não atende.'})
AADD(aMsgRetorno, {413,'Resposta de erro do Cliente','A entidade requisição é maior do que os limites definidos pelo servidor; o servidor pode fechar a conexão ou retornar um campo de cabeçalho Retry-After. '})
AADD(aMsgRetorno, {414,'Resposta de erro do Cliente','A URI requisitada pelo cliente é maior do que o servidor aceita para interpretar.'})
AADD(aMsgRetorno, {415,'Resposta de erro do Cliente','O formato de mídia dos dados requisitados não é suportado pelo servidor, então o servidor rejeita a requisição.'})
AADD(aMsgRetorno, {416,'Resposta de erro do Cliente','O trecho especificado pelo campo Range do cabeçalho na requisição não pode ser preenchido; é possível que o trecho esteja fora do tamanho dos dados da URI alvo.'})
AADD(aMsgRetorno, {417,'Resposta de erro do Cliente','Este código de resposta significa que a expectativa indicada pelo campo Expect do cabeçalho da requisição não pode ser satisfeita pelo servidor.'})
AADD(aMsgRetorno, {418,'Resposta de erro do Cliente','O servidor recusa a tentativa de coar café num bule de chá'})
AADD(aMsgRetorno, {421,'Resposta de erro do Cliente','A requisição foi direcionada a um servidor inapto a produzir a resposta. Pode ser enviado por um servidor que não está configurado '+hb_osnewline() +; 
                                                     'para produzir respostas para a combinação de esquema ("scheme") e autoridade inclusas na URI da requisição.'})
AADD(aMsgRetorno, {422,'Resposta de erro do Cliente','A requisição está bem formada mas inabilitada para ser seguida devido a erros semânticos.'})
AADD(aMsgRetorno, {423,'Resposta de erro do Cliente' ,'O recurso sendo acessado está travado.'})
AADD(aMsgRetorno, {424,'Resposta de erro do Cliente','A requisição falhou devido a falha em requisição prévia.'})
AADD(aMsgRetorno, {425,'Resposta de erro do Cliente','Indica que o servidor não está disposto a arriscar processar uma requisição que pode ser refeita.'})
AADD(aMsgRetorno, {426,'Resposta de erro do Cliente','O servidor se recusa a executar a requisição usando o protocolo corrente mas estará pronto a fazê-lo após o cliente atualizar '+hb_osnewline() +; 
                                                     'para um protocolo diferente. O servidor envia um cabeçalho Upgrade (en-US) numa resposta 426 para indicar o(s) protocolo(s) requeridos.'})
AADD(aMsgRetorno, {428,'Resposta de erro do Cliente','O servidor de origem requer que a resposta seja condicional. Feito para prevenir o problema da atualização perdida,'+hb_osnewline() +; 
                                                     'onde um cliente pega o estado de um recurso (GET) , modifica-o, e o põe de volta no servidor (PUT), enquanto um terceiro '+hb_osnewline() +; 
                                                     'modificou o estado no servidor, levando a um conflito.'})
AADD(aMsgRetorno, {429,'Resposta de erro do Cliente','O usuário enviou muitas requisições num dado tempo ("limitação de frequência").'})
AADD(aMsgRetorno, {431,'Resposta de erro do Cliente','O servidor não quer processar a requisição porque os campos de cabeçalho são muito grandes. '+hb_osnewline() +; 
                                                     'A requisição PODE ser submetida novemente depois de reduzir o tamanho dos campos de cabeçalho.'})
AADD(aMsgRetorno, {451,'Resposta de erro do Cliente','O usuário requisitou um recurso ilegal, tal como uma página censurada por um governo.'})

AADD(aMsgRetorno, {500,'Resposta de erro do Servidor','O servidor encontrou uma situação com a qual não sabe lidar.'})
AADD(aMsgRetorno, {501,'Resposta de erro do Servidor','O método da requisição não é suportado pelo servidor e não pode ser manipulado. '+hb_osnewline() +; 
                                                      'Os únicos métodos exigidos que servidores suportem (e portanto não devem retornar este código) são GET e HEAD.'})
AADD(aMsgRetorno, {502,'Resposta de erro do Servidor','Esta resposta de erro significa que o servidor, ao trabalhar como um gateway a fim de obter uma resposta necessária '+hb_osnewline() +;
                                                      'para manipular a requisição, obteve uma resposta inválida.'})
AADD(aMsgRetorno, {503,'Resposta de erro do Servidor','O servidor não está pronto para manipular a requisição.'+hb_osnewline() +; 
                                                      ' Causas comuns são um servidor em manutenção ou sobrecarregado. '+hb_osnewline() +; 
                                                       'Note que junto a esta resposta, uma página amigável explicando o problema deveria ser enviada. '+hb_osnewline() +; 
                                                       'Estas respostas devem ser usadas para condições temporárias e o cabeçalho HTTP Retry-After: deverá, se possível, '+hb_osnewline() +;
                                                       'conter o tempo estimado para recuperação do serviço. O webmaster deve também tomar cuidado com os cabeçalhos '+hb_osnewline() +; 
                                                       'relacionados com o cache que são enviados com esta resposta, já que estas respostas de condições temporárias '+hb_osnewline() +;
                                                       'normalmente não deveriam ser postas em cache.'})
AADD(aMsgRetorno, {504,'Resposta de erro do Servidor','Esta resposta de erro é dada quando o servidor está atuando como um gateway e não obtém uma resposta a tempo.'})
AADD(aMsgRetorno, {505,'Resposta de erro do Servidor','A versão HTTP usada na requisição não é suportada pelo servidor.'})
AADD(aMsgRetorno, {506,'Resposta de erro do Servidor','O servidor tem um erro de configuração interno: a negociação transparente de conteúdo para a requisição resulta '+hb_osnewline() +;
                                                      'em uma referência circular.'})
AADD(aMsgRetorno, {507,'Resposta de erro do Servidor','O servidor tem um erro interno de configuração: o recurso variante escolhido está configurado para entrar em '+hb_osnewline() +; 
                                                      'negociação transparente de conteúdo com ele mesmo, e portanto não é uma ponta válida no processo de negociação.'})
AADD(aMsgRetorno, {508,'Resposta de erro do Servidor','O servidor detectou um looping infinito ao processar a requisição.'})
AADD(aMsgRetorno, {510,'Resposta de erro do Servidor','Exigem-se extensões posteriores à requisição para o servidor atendê-la.'})
AADD(aMsgRetorno, {511,'Resposta de erro do Servidor','O código de status 511 indica que o cliente precisa se autenticar para ganhar acesso à rede.'})

nScan:= ASCAN(aMsgRetorno, {|x| x[1]=::nHttpcode  } )
IF nScan > 0
   ::cRetorno := ::cRetorno + aMsgRetorno[nScan,2]+':'+ALLTRIM(STR(aMsgRetorno[nScan,1]))+ ' - '+aMsgRetorno[nScan,3]
   //Showmsg_Edit(ALLTRIM(STR(aMsgRetorno[nScan,1]))+ ' - '+aMsgRetorno[nScan,3] ,aMsgRetorno[nScan,2] )
ELSE 
   /*
   Isso não pode está na classe, se precisar tem que ler o ::cRetorno onde está chamando a classe - Leonardo Machado - 13/06/2023
   Showmsg_Edit( ::cRetorno ,'Erro Inesperado' )
   */
ENDIF

RETURN NIL
Exmplo de uso:

Código: Selecionar todos

   oWeb:=oSyg_curl():New()
   
   WITH OBJECT oWeb

      :cUrl       := 'https://olinda.bcb.gov.br/olinda/servico/Informes_Agencias/versao/v1/odata/Agencias?$format=json'
      :cHttpReq   := 'GET'
      :lJsonDecode:= .T.
      IF !:SendHttp()  // .T. deu certo , .F. ocorreu erro
         lRET:=.F.
      ENDIF
      
      ::hAgencias := :hResposta // aqui guarda a resposta em um HASH

      :End()
   END
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por Kapiaba »

Obrigado Leonardo, problema resolvido com XHBBCC77 y BCC77. Veja aqui que show() de bola.

FiveWin é o bicho, quando eu chamo... kkkkkkkkkkkkkkkkk

https://forums.fivetechsupport.com/view ... 3&start=60

Estas novas versões dos compiladores, estão maravilhosas.

Reagrds, saludos.
Avatar do usuário
sygecom
Administrador
Administrador
Mensagens: 7131
Registrado em: 21 Jul 2006 10:12
Localização: Alvorada-RS
Contato:

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por sygecom »

Kapiaba escreveu:Obrigado Leonardo, problema resolvido com XHBBCC77 y BCC77. Veja aqui que show() de bola.

FiveWin é o bicho, quando eu chamo... kkkkkkkkkkkkkkkkk

https://forums.fivetechsupport.com/view ... 3&start=60

Estas novas versões dos compiladores, estão maravilhosas.

Reagrds, Saludos.
Que bom que resolveu, objetivo é resolver e, seguir em frente. Abraços
Leonardo Machado
xHarbour.org + Hwgui + PostgreSql
claudiochaves
Usuário Nível 1
Usuário Nível 1
Mensagens: 35
Registrado em: 28 Jul 2017 15:48
Localização: campinas/sp

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por claudiochaves »

ola pessoal, eu ainda uso xharbour 1.0.0 e bcc 5.5.1 . Aonde encontro hbclass.ch , hbcurl.ch e hbcompat.ch?
Procurei nos includes do meu xhb e nao achei. Procurei no xhb 1.2.3 e também não achei.
Claudio Chaves
Desenvolvedor
Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por Kapiaba »

Bom dia. última versão do xHarbour:

https://forums.fivetechsupport.com/view ... 50#p274509

Se precisar de uma mais antiga, avise.

Abs.

Regards, saludos.
claudiochaves
Usuário Nível 1
Usuário Nível 1
Mensagens: 35
Registrado em: 28 Jul 2017 15:48
Localização: campinas/sp

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por claudiochaves »

Obrigado Kapiaba, vou procurar e baixar. O xHarbour não atualiza mais pelo svn?
Claudio Chaves
Desenvolvedor
claudiochaves
Usuário Nível 1
Usuário Nível 1
Mensagens: 35
Registrado em: 28 Jul 2017 15:48
Localização: campinas/sp

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por claudiochaves »

Encontrei o hbclass e hbcompat. Agora o hbcurl.ch não tem também. Alguém saberia informar aonde acho ele?
Claudio Chaves
Desenvolvedor
Kapiaba
Colaborador
Colaborador
Mensagens: 1908
Registrado em: 07 Dez 2012 16:14
Localização: São Paulo
Contato:

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por Kapiaba »

Código: Selecionar todos

 Pasta de C:\XHBBCC77\include

08/10/2024  14:20            31.698 hbcurl.ch
               1 arquivo(s)         31.698 bytes
Regards, saludos.
carlosbrito
Usuário Nível 1
Usuário Nível 1
Mensagens: 1
Registrado em: 29 Fev 2016 09:50
Localização: Juazeiro-Ba

Exemplo de uso de HBCURL.LIB para xHarbour?

Mensagem por carlosbrito »

Quando forem criar variavéis para Json, criem com Hash() e depois convertam para cJson se desejam transmitir por algum body:http
apllication/json, sem precisar criar com: cJson := '{ hnfe: { num: '+cNum+', Emissao: '+Dtoc(date)... dá muito trabalho criar cjson
dessa maneira.

// Criando exemplo variavel hash

hNfe := CreateObj()
hNfe:Num := 122 // vai ficar hNe:NUM se quiser em minuscula e maiuscula cria na string hnfe['Num'] :=
hNfe:Emissao := date()

hNfe:Destinatario := CreateObj()
hNfe:Destinatario:Cnpj := Cliente->Cnpj7
hNfe:Destinatario:Nome := Cliente->Nome4

hNfe:Total := CreateObj()
hNfe:Total:Vlrtotal := nfe->vlrtotal
hNfe:Total:Desconto := nfe->desconto
hNfe:Total:vlricms := nfe->vlricms

hNfe:Itens := {} // populando itens com array ou hash com código do item

For each hitem in hitens

Aadd(hnfe:itens, { hitem:codigo, hitem:Qtd, hitem:prc } )

// ou se tivesse criado hNfe:itens := CreateObj()
//
// hnfe:itens[nfeitens->codigo] := CreateObj()
// hne:itens[nfeitens->codigo]:qtd := nfeitens->qtd
// hne:itens[nfeitens->codigo]:prc := nfeitens->prc

Next

cJson := hb_jsonencode( hnfe, .T. ) // Transforma de hnfe (hash) para cJson:txt //

Return(cJson)

/* Criando o objeto hash */

Function CreateObj()

Local oObj := {=>}

HSetCaseMatch( oObj, .F. ) // desabilita o case-sensitive
HSetAutoAdd(oObj, .t.) // Adiciona obj:newvar

return( oObj )
Responder