Ayuda con codigo - conversion

Ayuda con codigo - conversion

Postby carlos vargas » Tue Oct 24, 2023 3:04 am

Hola estimados, necesito de su ayuda con este codigo, deseo pasarlo a harbour/fw, si bien le he dado muchas vueltas, no logro hace la parte del TMultipartFormData.Create()
agradezco cualquier ayuda brindada!

Code: Select all  Expand view
program sendFileByUpload;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Classes, System.Net.HttpClient, System.Net.Mime, System.Net.URLClient, System.Net.HttpClientComponent;

var
  HttpClient: TNetHTTPClient;
  Response: IHTTPResponse;
  FormData: TMultipartFormData;
  EndpointURL, ID_INSTANCE, API_TOKEN_INSTANCE: string;

begin
  ID_INSTANCE := '110100001';
  API_TOKEN_INSTANCE := 'd75b3a66374942c5b3c019c698abc2067e151558acbd451234';

  EndpointURL := 'https://api.green-api.com/waInstance' + ID_INSTANCE + '/sendFileByUpload/' + API_TOKEN_INSTANCE;

  HttpClient := TNetHTTPClient.Create(nil);

  FormData := TMultipartFormData.Create();
  FormData.AddField('chatId', '71234567890@c.us');
  FormData.AddField('caption', 'test');
  FormData.AddFile('file', 'C:\tmp\bp.png');

  try
    Response := HTTPClient.Post(EndpointURL, FormData, nil);

    if Response.StatusCode = 200 then
      Writeln('[Response]: ' + Response.ContentAsString)
    else
      Writeln('[ERROR ' + IntToStr(Response.StatusCode) + ']:' + Response.StatusText + '' + Response.ContentAsString);

    readln;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;

  HttpClient.Free;
  FormData.Free;

end.
Salu2
Carlos Vargas
Desde Managua, Nicaragua (CA)
User avatar
carlos vargas
 
Posts: 1720
Joined: Tue Oct 11, 2005 5:01 pm
Location: Nicaragua

Re: Ayuda con codigo - conversion

Postby Antonio Linares » Tue Oct 24, 2023 5:11 am

Estimado Carlos,

Supongo que habrás encontrado esto:

http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42099
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Ayuda con codigo - conversion

Postby Antonio Linares » Tue Oct 24, 2023 5:37 am

A ver si esto puede servirte:

Code: Select all  Expand view
// A class to represent a single part of a multipart/form-data
CLASS TFormDataPart
   DATA name // The name of the part
   DATA contentType // The content type of the part, or empty if not specified
   DATA filename // The filename of the part, or empty if not a file
   DATA data // The data of the part, as an array of bytes
   DATA dataSize // The size of the data in bytes

   // A constructor that takes the name and data of the part
   METHOD New( cName, aData )
      ::name := cName
      ::data := aData
      ::dataSize := Len( ::data )
      RETURN Self

   // A constructor that takes the name, content type, filename and data of the part
   METHOD NewWithFile( cName, cContentType, cFilename, aData )
      ::name := cName
      ::contentType := cContentType
      ::filename := cFilename
      ::data := aData
      ::dataSize := Len( ::data )
      RETURN Self

ENDCLASS

// A class to represent a multipart/form-data
CLASS TMultiPartFormData
   DATA parts // An array of parts
   DATA numParts // The number of parts in the array
   DATA boundary // A boundary string to separate the parts

   // A constructor that generates a random boundary string
   METHOD New()
      ::parts := {}
      ::numParts := 0
      ::boundary := ::generateBoundary()
      RETURN Self

   // A constructor that takes a custom boundary string
   METHOD NewWithBoundary( cBoundary )
      ::parts := {}
      ::numParts := 0
      ::boundary := cBoundary
      RETURN Self

   // A method to add a part to the multipart/form-data
   METHOD addPart( oPart )
      AAdd( ::parts, oPart )
      ::numParts++
      RETURN Self

   // A method to get the content type of the multipart/form-data
   METHOD getContentType()
      RETURN "multipart/form-data; boundary=" + ::boundary

   // A method to get the content length of the multipart/form-data
   METHOD getContentLength()
      nLength := 0
      FOR EACH oPart IN ::parts
         // Add the length of the boundary and the CRLF
         nLength += Len( ::boundary ) + 2
         // Add the length of the Content-Disposition header and the CRLF
         nLength += 38 + Len( oPart:name ) + 2
         IF !Empty( oPart:filename )
            // Add the length of the filename parameter and the CRLF
            nLength += 12 + Len( oPart:filename ) + 2
         ENDIF
         IF !Empty( oPart:contentType )
            // Add the length of the Content-Type header and the CRLF
            nLength += 16 + Len( oPart:contentType ) + 2
         ENDIF
         // Add an extra CRLF before the data
         nLength += 2
         // Add the length of the data and the CRLF
         nLength += oPart:dataSize + 2
      NEXT
      // Add the length of the final boundary and the CRLF
      nLength += Len( ::boundary ) + 4
      RETURN nLength

   // A method to write the multipart/form-data to an output stream
   METHOD writeToStream( oStream )
      FOR EACH oPart IN ::parts
         // Write the boundary and the CRLF
         oStream:WriteLine( "--" + ::boundary )
         // Write the Content-Disposition header and the CRLF
         oStream:WriteLine( "Content-Disposition: form-data; name=\"" + oPart:name + "\"" )
         IF !Empty( oPart:filename )
            // Write the filename parameter and the CRLF
            oStream:WriteLine( "; filename=\"" + oPart:filename + "\"" )
         ENDIF
         IF !Empty( oPart:contentType )
            // Write the Content-Type header and the CRLF
            oStream:WriteLine( "Content-Type: " + oPart:contentType )
         ENDIF
         // Write an extra CRLF before the data
         oStream:WriteLine()
         // Write the data and the CRLF
         oStream:WriteBytes( oPart:data )
         oStream:WriteLine()
      NEXT
      // Write the final boundary and the CRLF
      oStream:WriteLine( "--" + ::boundary + "--" )

ENDCLASS

// A helper function to generate a random boundary string
FUNCTION generateBoundary()
   // Use a random number generator
   Randomize()

   // Use 16 hexadecimal digits as the boundary
   cBoundary := "----"
   FOR i := 1 TO 16
      cBoundary += SubStr( "0123456789ABCDEF", Int( 16 * Random() ) + 1, 1 )
   NEXT
   RETURN cBoundary
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42099
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Ayuda con codigo - conversion

Postby Antonio Linares » Tue Oct 24, 2023 5:56 am

Y aqui la clase TStream:

Code: Select all  Expand view
// A class to represent a stream of bytes
CLASS TStream
   DATA position // The current position in the stream
   DATA size // The size of the stream in bytes

   // A constructor that sets the initial position and size of the stream
   METHOD New( nPosition, nSize )
      ::position := nPosition
      ::size := nSize
      RETURN Self
   END

   // A method to read a line of text from the stream, or NIL if the end of the stream is reached
   METHOD ReadLine()
      cLine := ""
      nByte := ::ReadByte()
      DO WHILE nByte != NIL .AND. nByte != 10 // 10 is the ASCII code for LF
         cLine += Chr( nByte )
         IF nByte == 13 // 13 is the ASCII code for CR
            nByte := ::ReadByte()
            IF nByte == 10 // 10 is the ASCII code for LF
               EXIT // End of line
            ELSE
               cLine += Chr( 13 ) + Chr( nByte ) // Append both CR and the next byte
            ENDIF
         ELSE
            nByte := ::ReadByte()
         ENDIF
      ENDDO
      IF Empty( cLine )
         RETURN NIL // End of stream
      ELSE
         RETURN cLine // Return the line without the CRLF
      ENDIF
   END

   // A method to write a line of text to the stream, followed by a CRLF
   METHOD WriteLine( cLine )
      ::WriteBytes( cLine + Chr( 13 ) + Chr( 10 ) ) // Append CRLF to the line
   END

   // A method to read a single byte from the stream, or NIL if the end of the stream is reached
   METHOD ReadByte()
      IF ::position < ::size
         nByte := ::getByte( ::position ) // Get the byte at the current position (to be implemented by subclasses)
         ::position++ // Increment the position
         RETURN nByte
      ELSE
         RETURN NIL // End of stream
      ENDIF
   END

   // A method to write a single byte to the stream
   METHOD WriteByte( nByte )
      IF ::position < ::size
         ::setByte( ::position, nByte ) // Set the byte at the current position (to be implemented by subclasses)
         ::position++ // Increment the position
      ELSE
         ::appendByte( nByte ) // Append the byte to the end of the stream (to be implemented by subclasses)
         ::position++ // Increment the position
         ::size++ // Increment the size
      ENDIF
   END

   // A method to read an array of bytes from the stream, or NIL if the end of the stream is reached
   METHOD ReadBytes( nCount )
      IF ::position + nCount <= ::size
         aBytes := ::getBytes( ::position, nCount ) // Get an array of bytes from the current position (to be implemented by subclasses)
         ::position += nCount // Increment the position by the number of bytes read
         RETURN aBytes
      ELSE
         RETURN NIL // End of stream or not enough bytes available
      ENDIF
   END

   // A method to write an array of bytes to the stream
   METHOD WriteBytes( aBytes )
      IF ::position + Len( aBytes ) <= ::size
         ::setBytes( ::position, aBytes ) // Set an array of bytes from the current position (to be implemented by subclasses)
         ::position += Len( aBytes ) // Increment the position by the number of bytes written
      ELSE
         FOR EACH nByte IN aBytes
            ::WriteByte( nByte ) // Write each byte individually
         NEXT
      ENDIF
   END

   METHOD WriteLine( cLine )
      ::WriteBytes( cLine + Chr( 13 ) + Chr( 10 ) ) // Append CRLF to the line
   END

ENDCLASS
 
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
 
Posts: 42099
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain

Re: Ayuda con codigo - conversion

Postby carlos vargas » Tue Oct 24, 2023 11:16 pm

Con la ayuda de César Gómez y la clase tposthtml logré enviar un archivo pero llega corrupto, hoy daré un vistazo a lo que envías Antonio, muy agradecido...

Les comentaré como me fue...

Salu2
Salu2
Carlos Vargas
Desde Managua, Nicaragua (CA)
User avatar
carlos vargas
 
Posts: 1720
Joined: Tue Oct 11, 2005 5:01 pm
Location: Nicaragua

Re: Ayuda con codigo - conversion

Postby carlos vargas » Wed Oct 25, 2023 2:50 am

Antonio, me parece que la clase tstream esta incompleta, est es derivada del vfp o xbase++?
lo digo por la sintasix de la definicion de clase, o es de las antiguas clase de clipper class(y)?

salu2
carlos
Salu2
Carlos Vargas
Desde Managua, Nicaragua (CA)
User avatar
carlos vargas
 
Posts: 1720
Joined: Tue Oct 11, 2005 5:01 pm
Location: Nicaragua

Re: Ayuda con codigo - conversion

Postby carlos vargas » Wed Oct 25, 2023 3:07 am

Code: Select all  Expand view
/*----------------------------------------------------------------------------*/
// CLASS TStream
/*----------------------------------------------------------------------------*/

CLASS TStream
   DATA nPosition
   DATA nSize

   METHOD New( nPosition, nSize ) CONSTRUCTOR
   METHOD ReadLine()
   METHOD WriteLine( cLine )
   METHOD ReadByte()
   METHOD WriteByte( nByte )
   METHOD ReadBytes( nCount )
   METHOD WriteBytes( aBytes )
   METHOD GetByte( nPosition ) VIRTUAL
   METHOD SetByte( nPosition, nByte )  VIRTUAL
   METHOD AppendByte( nByte ) VIRTUAL
   METHOD GetBytes( nPosition, nCount ) VIRTUAL
   METHOD SetBytes( nPosition, aBytes ) VIRTUAL
ENDCLASS

/*----------------------------------------------------------------------------*/

METHOD New( nPosition, nSize ) CLASS TStream
   ::nPosition := nPosition
   ::nSize     := nSize
RETURN Self

/*----------------------------------------------------------------------------*/

METHOD ReadLine() CLASS TStream
   LOCAL cLine := ""
   LOCAL nByte := ::ReadByte()

   WHILE nByte != NIL .AND. nByte != 10
      cLine += Chr( nByte )
      IF nByte == 13
         nByte := ::ReadByte()
         IF nByte == 10
            EXIT
         ELSE
            cLine += Chr( 13 ) + Chr( nByte )
         ENDIF
      ELSE
         nByte := ::ReadByte()
      ENDIF
   ENDDO

   IF Empty( cLine )
      RETURN NIL
   ELSE
      RETURN cLine
   ENDIF

RETURN NIL

/*----------------------------------------------------------------------------*/

METHOD WriteLine( cLine ) CLASS TStream
   ::WriteBytes( cLine + Chr( 13 ) + Chr( 10 ) )
RETURN NIL

/*----------------------------------------------------------------------------*/

METHOD ReadByte() CLASS TStream
   LOCAL nByte
   IF ::nPosition < ::nSize
      nByte := ::GetByte( ::nPosition )
      ::nPosition++
      RETURN nByte
   ELSE
      RETURN NIL
   ENDIF
RETURN NIL

/*----------------------------------------------------------------------------*/

METHOD WriteByte( nByte ) CLASS TStream
   IF ::nPosition < ::nSize
      ::SetByte( ::nPosition, nByte )
      ::nPosition++
   ELSE
      ::AppendByte( nByte )
      ::nPosition++
      ::nSize++
   ENDIF
RETURN NIL

/*----------------------------------------------------------------------------*/

METHOD ReadBytes( nCount ) CLASS TStream
   LOCAL aBytes
   IF ::nPosition + nCount <= ::nSize
      aBytes := ::GetBytes( ::nPosition, nCount )
      ::nPosition += nCount
      RETURN aBytes
   ELSE
      RETURN NIL
   ENDIF
RETURN NIL

/*----------------------------------------------------------------------------*/

METHOD WriteBytes( aBytes ) CLASS TStream
   IF ::nPosition + Len( aBytes ) <= ::nSize
      ::SetBytes( ::nPosition, aBytes )
      ::nPosition += Len( aBytes )
   ELSE
      FOR EACH nByte IN aBytes
         ::WriteByte( nByte )
      NEXT
   ENDIF
RETURN NIL
Salu2
Carlos Vargas
Desde Managua, Nicaragua (CA)
User avatar
carlos vargas
 
Posts: 1720
Joined: Tue Oct 11, 2005 5:01 pm
Location: Nicaragua


Return to FiveWin para Harbour/xHarbour

Who is online

Users browsing this forum: No registered users and 49 guests