Page 1 of 1
Ayuda con codigo - conversion
Posted: Tue Oct 24, 2023 3:04 am
by carlos vargas
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
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.
Re: Ayuda con codigo - conversion
Posted: Tue Oct 24, 2023 5:11 am
by Antonio Linares
Re: Ayuda con codigo - conversion
Posted: Tue Oct 24, 2023 5:37 am
by Antonio Linares
A ver si esto puede servirte:
Code: Select all | Expand
// 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
Re: Ayuda con codigo - conversion
Posted: Tue Oct 24, 2023 5:56 am
by Antonio Linares
Y aqui la clase TStream:
Code: Select all | Expand
// 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
Re: Ayuda con codigo - conversion
Posted: Tue Oct 24, 2023 11:16 pm
by carlos vargas
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
Re: Ayuda con codigo - conversion
Posted: Wed Oct 25, 2023 2:50 am
by carlos vargas
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
Re: Ayuda con codigo - conversion
Posted: Wed Oct 25, 2023 3:07 am
by carlos vargas
Code: Select all | Expand
/*----------------------------------------------------------------------------*/
// 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