Funciones suplementarias para la librería _pop3.au3
Publicado: 22 Feb 2009, 20:26
Bueno bueno.......siguiendo al mensaje de Jonny (http://www.emesn.com/autoitforum/viewto ... f=3&t=1464), he ampliado la librería de Luc HENNINOT <[email protected]> (_pop3.au3).
Le he añadido varias funciones para descargar las propiedades del mensaje, el cuerpo y otra función que te dice si el mensaje tiene o no archivos adjuntos. Todo esto sin necesidad de tener que descargar todo el mensaje. Vamos....que lo hace bastante rápido y apenas bloquea el script .
También he añadido otra función que te descarga los archivos adjuntos y los graba en la ubicación dada por el usuario.
No están muy depuradas. Puede tener fallos. El tratamiento de errores no está muy probado.
Tampoco lo he probado con muchos mails. Puede que si se envían desde otros servidores o desde otros programas de envío de mensajes el texto sea diferente y falle. Espero que no . Yo lo he probado con hotmail (webmail).
Por cierto....me han costado un poquito hacerlas ya que no tenía ni idea del protocolo pop . Pero pronto se aprende .
El código del archivo _pop3_ampliado.au3 es: EDITADO EL CÓDIGO DE _POP_AMPLIADO.AU3. MEJORADO Y CORREGIDO FALLOS
El código de un ejemplo:
Espero que os gusten.
Voy a subir las librerías originales. Estas son _pop3.au3, _pop3_ampliado.au3, base64.au3. También subo un ejemplo.
SUBIDO EL NUEVO ARCHIVO CON EL NUEVO CÓDIGO DE LA LIBRERÍA _POP_AMPLIADO.AU3
Las direcciones url de los archivos, se encuentran en las explicaciones de las funciones.
Espero que os guste.
Saludos .
Le he añadido varias funciones para descargar las propiedades del mensaje, el cuerpo y otra función que te dice si el mensaje tiene o no archivos adjuntos. Todo esto sin necesidad de tener que descargar todo el mensaje. Vamos....que lo hace bastante rápido y apenas bloquea el script .
También he añadido otra función que te descarga los archivos adjuntos y los graba en la ubicación dada por el usuario.
No están muy depuradas. Puede tener fallos. El tratamiento de errores no está muy probado.
Tampoco lo he probado con muchos mails. Puede que si se envían desde otros servidores o desde otros programas de envío de mensajes el texto sea diferente y falle. Espero que no . Yo lo he probado con hotmail (webmail).
Por cierto....me han costado un poquito hacerlas ya que no tenía ni idea del protocolo pop . Pero pronto se aprende .
El código del archivo _pop3_ampliado.au3 es: EDITADO EL CÓDIGO DE _POP_AMPLIADO.AU3. MEJORADO Y CORREGIDO FALLOS
Código: Seleccionar todo
;-----------------------_POP3.AU3---------------------------
;~ Basic functions for AU3 Scripts, based on the 1939 RFC.
;~ See http://www.ietf.org/rfc/rfc1939.txt
;~ Include version : 0.99 (March 2006, 9th).
;~ Requires AU3 beta version 3.1.1.110 or newer.
;~ Author : Luc HENNINOT <[email protected]>
;-----------------------------------------------------------
;~ Int _pop3Connect (server, login, passwd [, port])
; Conects to the according pop3 server. Returns 0 for OK, -1 if error and sets @error. Server can be an IP address, or a full text name.
;~ String _Pop3Dele(msg_number)
; Delete msg n° msg_number. Returns the server response or -1 if error, and sets @error.
;~ Array _Pop3List([msg_number])
; Returns an array with the msg number and its size (octets), -1 if error ans sets @error.
;~ String _Pop3Noop()
; Actually, does nothing. The most interesting command from RFC 1939 ;)
;~ String _Pop3Quit()
; Validates your actions (dele for example) and stops the connection as it should. Returns the server response, or -1 and sets @error.
;~ String _Pop3Retr(msg_number) ; Downloads the according message, or returns -1 and sets @error.
;~ Int _Pop3Rset() ; Withdraw changes, such as dele orders. Returns 0 for success, -1 for error and sets @error.
;~ Array _Pop3Stat() ; Sends the number of messages in the pop3 account (array[1]) and the size(array[2]) in octets, or -1 ans sets @error.
;~ Sting _Pop3Top(msg_number, lines) ; Retreives the mail headers, and the X first lines of the message. Or returns -1 and sets @error.
;~ Array _Pop3Uidl([msg_number]) ; Same as _Pop3List(), but with UIDL identifiers instead of message size.
;~ Subfunctions, used by the above ones --------------------
;~ Int _pop3Disconnect() ; Shuts down connection. Returns 0 for OK, -1 if error and sets @error. Use _Pop3Quit to exit !!
;~ Sting _Pop3WaitForOK() ; Returns the server response if it starts with "+OK", or -1 and sets @error.
;~ String _WaitTcpResponse() ; Returns the server response, or -1 and sets @error.
#include-once
#include <array.au3>
#include <String.au3>
; -- _POP3 error codes, sent by SetError. Use @error to display it. --
Global Const $pop3_error_tcpconnect_failed=1
Global Const $pop3_error_server_response_timeout=2
Global Const $pop3_error_already_connected=3
Global Const $pop3_error_not_connected=4
Global Const $pop3_error_no_auth=5
Global Const $pop3_error_tcprecv_timeout=6
Global Const $pop3_error_user_refused=7
Global Const $pop3_error_passwd_refused=8
Global Const $pop3_error_no_OK_response=9
Global Const $pop3_error_stat_badresponse=10
Global Const $pop3_error_no_TCP_response=11
Global Const $pop3_error_stat_refused=12
Global Const $pop3_error_list_refused=13
Global Const $pop3_error_rset_refused=14
Global Const $pop3_error_retr_refused=15
Global Const $pop3_error_quit_refused=16
Global Const $pop3_error_dele_refused=17
Global Const $pop3_error_top_refused=18
Global Const $pop3_error_uidl_refused=19
Global Const $pop3_error_noop_refused=20 ; I love this one ;)
;-- _POP3 vars --
Global Const $POP3_OK = "^\+OK"; Regexp syntax
Global Const $POP3_ERR = "^-ERR"; Unused yet, may help later.
Global $pop3_IsConnected = 0
Global $pop3_IsAuth = 0
Global $pop3_socket
Global $pop3_server_response_timeout = 60000 ; 1 mn, modify it if needed
;-- _POP3 Funcs --
Func _pop3Connect($server, $login, $passwd, $port=110)
Local $ret
If $pop3_IsConnected = 0 Then
Local $server2
TCPStartUp ()
; Basic name to IP conversion
If StringRegExp($server, "[a-zA-Z]") Then
$server2 = TCPNameToIP ($server)
Else
$server2 = $server
EndIf
$pop3_socket = TCPConnect ($server2, $port)
If @error Then
SetError($pop3_error_tcpconnect_failed)
Return -1
Else
$pop3_IsConnected = 1
EndIf
; We need a first OK from pop3 server
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
; Send user
$ret = TCPSend ($pop3_socket, "USER " & $login & @CRLF)
If @error Then
SetError($pop3_error_user_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
; Send passwd
$ret = TCPSend ($pop3_socket, "PASS " & $passwd & @CRLF)
If @error Then
SetError($pop3_error_passwd_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
$pop3_IsAuth = 1
Return 0
Else
SetError($pop3_error_already_connected)
Return -1
EndIf
EndFunc ;==>_pop3Connect
Func _Pop3Stat()
If $pop3_IsAuth = 1 Then
Local $ret
Local $a_ret
; Send STAT
$ret = TCPSend ($pop3_socket, "STAT" & @CRLF)
If @error Then
SetError($pop3_error_stat_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
$a_ret = StringSplit($ret, " ")
If IsArray($a_ret) Then
_ArrayDelete($a_ret, 1)
$a_ret[0] = $a_ret[0] - 1
Return $a_ret
Else
SetError($pop3_error_stat_badresponse)
Return -1
EndIf
EndIf
EndFunc ;==>_Pop3Stat
Func _Pop3Noop()
If $pop3_IsAuth = 1 Then
Local $ret
Local $a_ret
; Send NOOP
$ret = TCPSend ($pop3_socket, "NOOP" & @CRLF)
If @error Then
SetError($pop3_error_noop_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
Return $ret
EndIf
EndFunc ;==>_Pop3Noop
Func _Pop3Rset()
If $pop3_IsAuth = 1 Then
Local $ret
; Send RSET
$ret = TCPSend ($pop3_socket, "RSET" & @CRLF)
If @error Then
SetError($pop3_error_rset_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
Return 0
EndIf
EndFunc ;==>_Pop3Rset
Func _Pop3List($msg = -1)
If $pop3_IsAuth = 1 Then
Local $ret
Local $AddMsg = ""
If $msg <> - 1 Then
$AddMsg = " " & $msg
EndIf
; Send List
$ret = TCPSend ($pop3_socket, "LIST" & $AddMsg & @CRLF)
If @error Then
SetError($pop3_error_list_refused)
Return -1
EndIf
$ret = _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
While $msg = -1 And Not StringRegExp($ret, "\r\n\.\r\n")
$ret = $ret & _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
WEnd
; Stripping useless infos for complete listing
$ret = StringSplit(StringStripCR($ret), @LF)
If $msg = -1 Then
_ArrayDelete($ret, $ret[0])
_ArrayDelete($ret, $ret[0] - 1)
_ArrayDelete($ret, 1)
$ret[0] = $ret[0] - 3
Else
_ArrayDelete($ret, $ret[0])
$ret[0] = $ret[0] - 1
$ret[1] = StringReplace($ret[1], "+OK ", "")
EndIf
Return $ret
EndIf
EndFunc ;==>_Pop3List
Func _Pop3Uidl($msg = -1)
If $pop3_IsAuth = 1 Then
Local $ret
Local $AddMsg = ""
If $msg <> - 1 Then
$AddMsg = " " & $msg
EndIf
; Send List
$ret = TCPSend ($pop3_socket, "UIDL" & $AddMsg & @CRLF)
If @error Then
SetError($pop3_error_uidl_refused)
Return -1
EndIf
$ret = _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
While $msg = -1 And Not StringRegExp($ret, "\r\n\.\r\n")
$ret = $ret & _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
WEnd
; Stripping useless infos for complete listing
$ret = StringSplit(StringStripCR($ret), @LF)
If $msg = -1 Then
_ArrayDelete($ret, $ret[0])
_ArrayDelete($ret, $ret[0] - 1)
_ArrayDelete($ret, 1)
$ret[0] = $ret[0] - 3
Else
_ArrayDelete($ret, $ret[0])
$ret[0] = $ret[0] - 1
$ret[1] = StringReplace($ret[1], "+OK ", "")
EndIf
Return $ret
EndIf
EndFunc ;==>_Pop3Uidl
Func _Pop3Retr($msg)
If $pop3_IsAuth = 1 Then
Local $ret
; Send Retr
$ret = TCPSend ($pop3_socket, "RETR " & $msg & @CRLF)
If @error Then
SetError($pop3_error_retr_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
$ret = _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
; Downloading until final dot and cariage return.
While Not StringRegExp($ret, "\r\n\.\r\n")
$ret = $ret & _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
WEnd
Return $ret
Else
SetError($pop3_error_no_auth)
Return -1
EndIf
EndFunc ;==>_Pop3Retr
Func _Pop3Top($msg, $nb)
If $pop3_IsAuth = 1 Then
Local $ret
; Send Top
$ret = TCPSend ($pop3_socket, "TOP " & $msg & " " & $nb & @CRLF)
If @error Then
SetError($pop3_error_top_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
$ret = _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
; Downloading until final dot and cariage return.
While Not StringRegExp($ret, "\r\n\.\r\n")
$ret = $ret & _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
WEnd
Return $ret
Else
SetError($pop3_error_no_auth)
Return -1
EndIf
EndFunc ;==>_Pop3Top
Func _Pop3Quit()
If $pop3_IsAuth = 1 Then
$ret = TCPSend ($pop3_socket, "QUIT" & @CRLF)
If @error Then
SetError($pop3_error_quit_refused)
Return -1
EndIf
$ret = _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
Return $ret
Else
SetError($pop3_error_no_auth)
Return -1
EndIf
EndFunc ;==>_Pop3Quit
Func _Pop3Dele($msg)
If $pop3_IsAuth = 1 Then
$ret = TCPSend ($pop3_socket, "DELE " & $msg & @CRLF)
If @error Then
SetError($pop3_error_dele_refused)
Return -1
EndIf
$ret = _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
Return $ret
Else
SetError($pop3_error_no_auth)
Return -1
EndIf
EndFunc ;==>_Pop3Dele
Func _pop3Disconnect()
If $pop3_IsConnected <> 0 Then
TCPCloseSocket ($pop3_socket)
TCPShutDown ()
$pop3_IsConnected = 0
Return 0
Else
SetError($pop3_error_not_connected)
Return -1
EndIf
EndFunc ;==>_pop3Disconnect
Func _Pop3WaitForOK()
; Wait for server response.
Local $ret
Local $T = TimerInit()
While 1
If TimerDiff($T) > $pop3_server_response_timeout Then
SetError($pop3_error_server_response_timeout)
Return -1
EndIf
$ret = _WaitTcpResponse()
If Not @error And StringRegExp($ret, $POP3_OK) Then
Return $ret
EndIf
Sleep(10)
WEnd
SetError($pop3_error_no_OK_response)
Return -1
EndFunc ;==>_Pop3WaitForOK
Func _WaitTcpResponse($timeout = 30000)
;Timeout to 30 s, should be enough in most cases. Overwright it if needed.
Local $ret
Local $T = TimerInit()
While 1
If TimerDiff($T) > $timeout Then
SetError($pop3_error_tcprecv_timeout)
Return -1
EndIf
$ret = TCPRecv ($pop3_socket, 128)
If $ret <> "" Then
Return $ret
EndIf
Sleep(10)
WEnd
EndFunc ;==>_WaitTcpResponse
;***********************************************************
;Funciones suplementarias de chefito ;)
;Menudo trabajazo que me han llevado las cabro..... jajajaja
;Estas funciones van junto a las de arriba, las de la librería _pop.au3
;***********************************************************
#cs *********************************************************************************
Función: _Pos3InfoMail($msg)
Descripción: Te da información del mensaje. Quien lo ha enviado, a quien, asunto del mail y fecha de envio.
Parámetros dados: Tiene 1. $msg: recibe el número del mensaje del que quieres la información.
Parámetros devueltos: Te devuelve un array con 4 elementos:
0 quien lo ha enviado.
1 a quien lo ha enviado.
3 asunto del mensaje.
4 fecha de envio del mensaje.
Si alguno de estos elementos falla, te devolvería 0.
Si falla la función totalmente, devuelve -1. Mirar @error.
Autor: Chefito 18/02/2009
Otros: Como siempre es libre. Se agradecería que se nombrase al Autor si se utiliza ;)=.
Y por supuesto, si se puede mejorar...adelante ;).
#ce *********************************************************************************
Func _Pop3InfoMail($msg)
Local $ret
If $pop3_IsAuth = 1 Then
Local $ret
$ret = TCPSend ($pop3_socket, "TOP " & $msg & " 0" & @CRLF)
If @error Then
SetError($pop3_error_retr_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
$ret = _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
Local $TotalText=""
Local $FromNoEncontrado=1,$ToNoEncontrado=1,$SubjectNoEncontrado=1
Local $Origen, $Destino, $Asunto, $Fecha, $posIni, $posFin
Local $DatosDevueltos[4]
For $n=0 To 3
$DatosDevueltos[$n]=0
Next
$ret=""
While Not StringRegExp($ret, "\r\n\.\r\n") ;****
$ret = $ret & _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
If $FromNoEncontrado Then
$posIni=StringInStr($ret,"From: ")
If $posIni<>0 Then
$posIni=$posIni+6
$posFin=StringInStr($ret,@CRLF,0,1,$posIni)
If $posFin<>0 Then
$Origen=StringMid($ret,$posIni,$posFin-$posIni)
$DatosDevueltos[0]=$Origen
$FromNoEncontrado=0
EndIf
EndIf
EndIf
If $ToNoEncontrado Then
$posIni=StringInStr($ret,"To: ")
If $posIni<>0 Then
$posIni=$posIni+5
$posFin=StringInStr($ret,">" & @CRLF,0,1,$posIni)
If $posFin<>0 Then
$Destino=StringMid($ret,$posIni,$posFin-$posIni)
$DatosDevueltos[1]=$Destino
$ToNoEncontrado=0
EndIf
EndIf
EndIf
If $SubjectNoEncontrado Then
$posIni=StringInStr($ret,"Subject: ")
If $posIni<>0 Then
$posIni=$posIni+9
$posFin=StringInStr($ret,@CRLF,0,1,$posIni)
If $posFin<>0 Then
$Asunto=StringMid($ret,$posIni,$posFin-$posIni)
$DatosDevueltos[2]=$Asunto
$SubjectNoEncontrado=0
EndIf
EndIf
EndIf
$posIni=StringInStr($ret,"Date: ")
If $posIni<>0 Then
$posIni=$posIni+6
$posFin=StringInStr($ret," +0100",0,1,$posIni)
If $posFin<>0 Then
$Fecha=StringMid($ret,$posIni,$posFin-$posIni)
$DatosDevueltos[3]=$Fecha
Return $DatosDevueltos
EndIf
EndIf
WEnd ;********
Return $DatosDevueltos
Else
SetError($pop3_error_no_auth)
Return -1
EndIf
EndFunc ;==>
#cs *********************************************************************************
Función: _Pop3CuerpoMail($msg,$MyPopServer, $MyLogin, $MyPasswd, $TextPlanoHtml=0, $modo=0)
Descripción: Te devuelve el texto plano o en HTML del mensaje.
Parámetros dados: Tiene 6.
$msg (obligatorio): recibe el número del mensaje del que quieres el texto.
$MyPopServer (obligatorio): recibe el servidor pop.
$MyLogin (obligatorio): recibe el login del correo.
$MyPasswd (obligatorio): recibe la clave del correo.
$TextoPlanoHtml (opcional): Si es 0 (por defecto), devuelve el mensaje en texto plano. Si
es distinto de 0 lo devuelve en código HTML.
$modo (opcional): recibe el modo de codificación del texto del mensaje. Si es 0 (por defecto)
te devuelve el texto tal cual. Si es distinto de 0, codifica caracteres especiales.
Parámetros devueltos: Te devuelve el texto del mensaje
Si falla la función, devuelve -1. Mirar @error.
Autor: Chefito 18/02/2009
Otros: He tenido que introducir los 3 parámetros $MyPopServer, $MyLogin, $MyPasswd porque por lo visto
se queda algo colgado el acceso al servidor pop a causa de cortar el mensaje antes de tiempo. Para
evitar que esté esperando un tiempo una respuesta erronea, he tenido que desconectar y conectar la
conexión con el servidor de nuevo. Si alguien encuentra una solución mejor que lo corrija y lo diga.
Como siempre es libre. Se agradecería que se nombrase al Autor si se utiliza ;)=.
Y por supuesto, si se puede mejorar...adelante ;).
#ce *********************************************************************************
Func _Pop3CuerpoMail($msg,$MyPopServer, $MyLogin, $MyPasswd, $TextPlanoHtml=0, $modo=0)
Local $ret
If $pop3_IsAuth = 1 Then
Local $ModoMsg, $longModoMsg
; Send Retr
If $TextPlanoHtml=0 Then
$ModoMsg="Content-Type: Text/plain;"
$longModoMsg=27
Else
$ModoMsg="Content-Type: Text/html;"
$longModoMsg=26
EndIf
$ret = TCPSend ($pop3_socket, "RETR " & $msg & @CRLF)
If @error Then
SetError($pop3_error_retr_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
$ret = _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
Local $TotalText="",$codigo2, $textoplano, $posIni=0, $posFin=0
Local $encontrarTexto=0,$encontrarClave=1,$encontrarHTML=0,$EncontrarCodigo2=0
$ret=""
;While Not StringRegExp($ret, "\r\n\.\r\n") ;****
While StringInStr($ret, "--" & $codigo2 & "--" & @CRLF)=0 ;****
$ret = $ret & _WaitTcpResponse()
If @error Then
;*********** Bloque de desconexión/conexión para que no se quede bloqueado el script ********
$desconectar=_pop3Disconnect()
If $desconectar<>-1 Then
$conectar=_pop3Connect($MyPopServer, $MyLogin, $MyPasswd)
If $conectar=-1 Then Return -1
Else
Return -1
EndIf
;*********** Fin bloque de desconexión/conexión para que no se quede bloqueado el script ********
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
If $EncontrarCodigo2=0 Then
$codigo2=_Codigo2($ret)
If $codigo2<>-1 Then $EncontrarCodigo2=1
EndIf
If $posIni=0 Then
$posIni=StringInStr($ret,$codigo2 & @CRLF & $ModoMsg)
If $posIni<>0 Then
$posIni=$posIni+StringLen($codigo2)+$longModoMsg
EndIf
EndIf
$posFin=StringInStr($ret,$Codigo2,0,1,$posIni)
If $posFin<>0 Then
$posIni=StringInStr($ret,"Content-Transfer-Encoding: quoted-printable",0,1,$posIni)+47
$TextoPlano=StringMid($ret,$posIni,$posFin-$posIni-6)
;*********** Bloque de desconexión/conexión para que no se quede bloqueado el script ********
$desconectar=_pop3Disconnect()
If $desconectar<>-1 Then
$conectar=_pop3Connect($MyPopServer, $MyLogin, $MyPasswd)
If $conectar=-1 Then Return -1
Else
Return -1
EndIf
;*********** Fin bloque de desconexión/conexión para que no se quede bloqueado el script ********
If $modo=0 Then
Return $TextoPlano
Else
$TextoPlano=ConvertirTextoUnicode($TextoPlano)
Return $TextoPlano
EndIf
EndIf
WEnd
;Return -1
Else
SetError($pop3_error_no_auth)
Return -1
EndIf
EndFunc
#cs *********************************************************************************
Función: _Pop3DescargarFicheros($msg, $path=@ScriptDir)
Descripción: Te descarga los ficheros adjuntos del mensaje y los guarda.
Parámetros dados: Tiene 2.
$msg (obligatorio): recibe el número del mensaje del que quieres el texto (0bligatorio).
$path (opcional): recibe el camino (path) donde se van a guardar los ficheros descargados.
Si no le pasas nada, por defecto los guarda en la ubicación del script.
Parámetros devueltos: Te devuelve una matriz (array) donde el elemento 0 tiene almacenados el número de
archivos bajado, y todos los elementos contienen el path más el nombre del archivo. Si falla
algún archivo, el elemento referente a este archivo contiene -1.
Si falla la función totalmente, devuelve -1. Mirar @error.
Autor: Chefito 18/02/2009
Otros: Como siempre es libre. Se agradecería que se nombrase al Autor si se utiliza ;)=.
Y por supuesto, si se puede mejorar...adelante ;).
#ce *********************************************************************************
Func _Pop3DescargarFicheros($msg, $path=@ScriptDir)
Local $ret
;***************** Bloque donde asigno los valores de las claves de comienzo y final de las distintas partes del mensaje ****
$ret=_Pop3Retr($msg)
If @error Then
SetError(@error)
Return -1
EndIf
$finCodigo2=_Codigo2($ret) & "--"
$Codigo1=_Codigo1($ret)
$IniCodigo1=@CRLF & @CRLF & "--" & $Codigo1
$IniCodigos=$fincodigo2 & $iniCodigo1 & @CRLF
$finCodigo1=$IniCodigo1 & "--"
;***************** Fin de bloque de asignación de claves *****************************************************************
$iniFicheros=StringInStr($ret,$IniCodigos) ;busca si hay ficheros en el mensaje.
If $iniFicheros<>0 Then
$longIniCodigos=StringLen($IniCodigos)
$ret=StringMid($ret,$iniFicheros + $longIniCodigos,StringLen($ret)-$longIniCodigos-$iniFicheros)
;************ Quita la clave final del mail ******************************************************************
;$ret=StringReplace($ret,$finCodigo1) ;también funciona con esta linea. Esta linea sustituiría a las 3 siguientes.
$posFinClave1=StringInStr($ret,$finCodigo1)
$longFicheros=StringLen($ret)
$ret=StringLeft($ret,$longFicheros-($longFicheros-$posFinClave1))
;************* Fin de bloque que quita la clave final del mail ************************************************
$ret=StringSplit($ret,$IniCodigo1,1)
For $n=1 To $ret[0] ;repito hasta guardar todos los ficheros.
;************* Busca y almacena el nombre del fichero ********************************
$posIniName=StringInStr($ret[$n],'filename="')+10
$posFinName=StringInStr($ret[$n],'"',0,1,$posIniName)
$nameFichero=StringMid($ret[$n],$posIniName,$posFinName-$posIniName)
;************* Fin de bloque de nombre del fichero ***********************************
$posIniFichero=$posFinName+5 ;Posición inicial del fichero. Adelanta 5 caracteres (2 @crlf).
$ret[$n]=StringMid($ret[$n],$posIniFichero,StringLen($ret[$n])) ;almaceno el código del fichero en Base 64.
$FicheroBinario=_Base64Decode($ret[$n]) ;lo descodifico convirtiendose en código binario.
$PathFichero=$path & "\" & $nameFichero ;path donde se va a guardar el fichero más el nombre de éste.
;***************** Bloque para crear y guardar el fichero descargardo **************************
$Fichero=FileOpen($PathFichero,2)
If $Fichero=-1 Then
$ret[$n]=-1
Else
$FicheroEscrito=FileWrite($Fichero,$FicheroBinario)
If $FicheroEscrito=0 Then
SetError(22) ;si no puede escribir en el fichero, @error=22
Return -1
EndIf
FileClose($Fichero)
$ret[$n]=$PathFichero
EndIf
;***************** Fin de bloque para crear y guardar el fichero descargado *********************
Next
Return $ret
Else ;Si no hay ficheros en el mensaje, la función devuelve 0
SetError(21) ;@error=21 indica que no hay ficheros en este mensaje.
Return -1
EndIf
EndFunc
#cs *********************************************************************************
Función: _Pop3ContieneAdjuntos($msg)
Descripción: Te dice si el mensaje contione o no archivos adjuntos.
Parámetros dados: Tiene 1.
$msg (obligatorio): recibe el número del mensaje del que quieres el texto (0bligatorio).
Parámetros devueltos: Si contiene algún archivo adjunto, la función devuelve 1, si no, devuelve -1 (@error=21)
Si falla la función totalmente, devuelve -1. Mirar @error.
Autor: Chefito 18/02/2009
Otros: Como siempre es libre. Se agradecería que se nombrase al Autor si se utiliza ;)=.
Y por supuesto, si se puede mejorar...adelante ;).
#ce *********************************************************************************
Func _Pop3ContieneAdjuntos($msg)
Local $ret
If $pop3_IsAuth = 1 Then
; Send Retr
$ret = TCPSend ($pop3_socket, "TOP " & $msg & " 0" & @CRLF)
If @error Then
SetError($pop3_error_retr_refused)
Return -1
EndIf
$ret = _Pop3WaitForOK()
If @error Then
SetError($pop3_error_no_OK_response)
Return -1
EndIf
$ret = _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
Local $TotalText="", $codigo1
$ret=""
While Not StringRegExp($ret, "\r\n\.\r\n") ;****
$ret = $ret & _WaitTcpResponse()
If @error Then
SetError($pop3_error_no_TCP_response)
Return -1
EndIf
$codigo1=StringInStr($ret,"Content-Type: multipart/mixed;")
If $codigo1<>0 Then Return 1
WEnd
SetError(21) ;@error=21 indica que no hay ficheros en este mensaje.
Return -1
Else
SetError($pop3_error_no_auth)
Return -1
EndIf
EndFunc
#cs *********************************************************************************
Funciones complementarias: Son funciones necesarias para las de arriba.
Descripción: ConvertirTextoUnicode($Texto) -> convierte texto del mensaje Unicode.
_Codigo1($Texto) -> Devuelve el primer código único del mensaje.
Suele indicar el comienzo y final de los archivos adjuntos.
_Codigo2($Texto) -> Devuelve el segundo código único del mensaje.
Suele indicar el comienzo y final del cuerpo del mensaje.
Autor: Chefito 18/02/2009
Otros: Como siempre es libre. Se agradecería que se nombrase al Autor si se utiliza ;)=.
Y por supuesto, si se puede mejorar...adelante ;).
#ce *********************************************************************************
Func ConvertirTextoUnicode($Texto)
Local $posIgual=0, $caracter
While 1
$posIgual=StringInStr($texto,"=",0,1,$posIgual+1)
If $posIgual<>0 Then
$caracter=StringMid($Texto,$posIgual+1,2)
If StringIsXDigit($caracter) Then
$texto=StringReplace($texto,"=" & $caracter,ChrW("0x" & $caracter),1)
EndIf
Else
$texto=StringReplace($texto,"=" & @CRLF,"")
$texto=StringLeft($texto,StringLen($texto)-1)
Return $texto
EndIf
If @error Then
Return -1
EndIf
WEnd
EndFunc
Func _Codigo1($texto)
Local $Codigo, $posIni, $posFin
$posIni=StringInStr($texto,"Content-Type: multipart/mixed;" & @CRLF & Chr(9) & 'boundary="')
If $posIni<>0 Then
$posIni=$posIni+43
$posFin=StringInStr($texto,'"',0,1,$posIni)
If $posFin<>0 Then
$Codigo=StringMid($texto,$posIni,$posFin-$posIni)
Return $Codigo
EndIf
Else
Return -1
EndIf
EndFunc
Func _Codigo2($texto)
Local $Codigo, $posIni, $posFin
$posIni=StringInStr($texto,"Content-Type: multipart/alternative;" & @CRLF & Chr(9) & 'boundary="')
If $posIni<>0 Then
$posIni=$posIni+49
$posFin=StringInStr($texto,'"',0,1,$posIni)
If $posFin<>0 Then
$Codigo=StringMid($texto,$posIni,$posFin-$posIni)
Return $Codigo
EndIf
Else
Return -1
EndIf
EndFunc
;*************************************************************************************
;Fin de funciones de Chefito :/
;*************************************************************************************
#cs Función _Base64Decode($Data)
;Descodifica un mensaje en Base 64. En mi caso la utilizo para descodificar los ficheros adjuntos del mensaje a binario.
;La conseguí en el foro ingles http://www.autoitscript.com/forum/index.php?showtopic=76976&st=0, de una UDF.
;Es una UDF con muchos métodos de codificación y descodificación. Rápida y poco tamaño. Muy recomendable tenerla.
#ce SU AUTOR ES Ward.
Func _Base64Decode($Data)
Local $Opcode = "0xC81000005356578365F800E8500000003EFFFFFF3F3435363738393A3B3C3DFFFFFF00FFFFFF000102030405060708090A0B0C0D0E0F10111213141516171819FFFFFFFFFFFF1A1B1C1D1E1F202122232425262728292A2B2C2D2E2F303132338F45F08B7D0C8B5D0831D2E9910000008365FC00837DFC047D548A034384C0750383EA033C3D75094A803B3D75014AB00084C0751A837DFC047D0D8B75FCC64435F400FF45FCEBED6A018F45F8EB1F3C2B72193C7A77150FB6F083EE2B0375F08A068B75FC884435F4FF45FCEBA68D75F4668B06C0E002C0EC0408E08807668B4601C0E004C0EC0208E08847018A4602C0E00624C00A46038847028D7F038D5203837DF8000F8465FFFFFF89D05F5E5BC9C21000"
Local $CodeBuffer = DllStructCreate("byte[" & BinaryLen($Opcode) & "]")
DllStructSetData($CodeBuffer, 1, $Opcode)
Local $Ouput = DllStructCreate("byte[" & BinaryLen($Data) & "]")
Local $Ret = DllCall("user32.dll", "int", "CallWindowProc", "ptr", DllStructGetPtr($CodeBuffer), _
"str", $Data, _
"ptr", DllStructGetPtr($Ouput), _
"int", 0, _
"int", 0)
Return BinaryMid(DllStructGetData($Ouput, 1), 1, $Ret[0])
EndFunc
Código: Seleccionar todo
#include <array.au3>
#include <_pop3_ampliado.au3>
ConsoleWrite(@AutoItVersion & @CRLF)
;~ See _pop3.au3 for a complete description of the pop3 functions
;~ Requires AU3 beta version 3.1.1.110 or newer.
Global $MyPopServer = "mail.ivermedia.com"
Global $MyLogin = "[email protected]"
Global $MyPasswd = "cvkjsp0lvk9"
_pop3Connect($MyPopServer, $MyLogin, $MyPasswd)
If @error Then
MsgBox(0, "Error", "Unable to connect to " & $MyPopServer & @CR & @error)
Exit
Else
ConsoleWrite("Connected to server pop3 " & $MyPopServer & @CR)
EndIf
;Local $stat = _Pop3Stat()
;If Not @error Then
; _ArrayDisplay($stat, "Result of STAT COMMAND")
;Else
; ConsoleWrite("Stat commande failed" & @CR)
;EndIf
;~ Local $list = _Pop3List()
;~ If Not @error Then
;~ _ArrayDisplay($list, "")
;~ Else
;~ ConsoleWrite("List commande failed" & @CR)
;~ EndIf
;~ Local $noop = _Pop3Noop()
;~ If Not @error Then
;~ ConsoleWrite($noop & @CR)
;~ Else
;~ ConsoleWrite("List commande failed" & @CR)
;~ EndIf
;~ Local $uidl = _Pop3Uidl()
;~ If Not @error Then
;~ _ArrayDisplay($uidl, "")
;~ Else
;~ ConsoleWrite("Uidl commande failed" & @CR)
;~ EndIf
;~ Local $top = _Pop3Top(3, 0)
;~ If Not @error Then
;~ ConsoleWrite(StringStripCR($top) & @CR)
;~ Else
;~ ConsoleWrite("top commande failed" & @CR)
;~ EndIf
#cs
MsgBox(0,"","Se va a proceder a descargar todo el mensaje en la ventana inferior de mensajes del Scite")
Local $retr = _Pop3Retr(2)
If Not @error Then
ConsoleWrite(StringStripCR($retr) & @CR)
Else
ConsoleWrite("Retr commande failed" & @CR)
EndIf
#ce
;~ Local $dele = _Pop3Dele(1)
;~ If Not @error Then
;~ ConsoleWrite($dele & @CR)
;~ Else
;~ ConsoleWrite("Dele commande failed" & @CR)
;~ EndIf
;#cs
MsgBox(0,"","Se va a mostrar la información del mensaje número 2")
Local $info=_pop3infomail(2)
If $info<>-1 Then
MsgBox(0,"","De: " & $info[0] & @CR & "A: " & $info[1] & @CR & "Asunto: " & $info[2] & @CR & "Enviado con fecha: " & $info[3])
Else
MsgBox(0,"Error","Error. No se ha podido descargar la información del mensaje")
EndIf
;#ce
;#cs
MsgBox(0,"","Se va a mostrar el cuerpo del mensaje número 2")
Local $cuerpo=_pop3cuerpomail(4,$MyPopServer, $MyLogin, $MyPasswd,0,1)
If $cuerpo<>-1 Then
MsgBox(0,"Texto del mensaje",$cuerpo)
Else
MsgBox(0,"Error","No se puede mostrar el texto del mensaje")
EndIf
;#ce
Local $numMail=3
Local $hayficheros=_pop3contieneadjuntos($numMail)
If $hayficheros=1 Then
MsgBox(0,"","El mensaje " & $numMail & " contiene ficheros adjuntos")
Else
If @error=21 Then
MsgBox(0,"","El mensaje " & $numMail & " no contiene ficheros adjuntos")
Else
MsgBox(0,"Error","Ha habido algún error al acceder al mensaje")
EndIf
EndIf
;#cs
Local $numMail=4
MsgBox(0,"","Se va a descargar los archivos adjuntos del mensaje número " & $numMail)
Local $texto=""
Local $archivos=_Pop3DescargarFicheros($numMail)
Switch $archivos
Case 0
MsgBox(0,"Error","No hay archivos adjuntos")
Case not -1
For $n=1 to $archivos[0]
If $archivos[$n]<>-1 Then
$texto=$texto & "Ha sido descargado y guardado el archivo en: " & $archivos[$n] & @CR
Else
$texto=$texto & "El archivo " & $archivos[$n] & " no ha podido ser guardado" & @CR
EndIf
Next
MsgBox(0,"",$texto)
Case Else
MsgBox(0,"Error","No ha podido descargarse los archivos")
EndSwitch
;#ce
ConsoleWrite(_Pop3Quit() & @CR)
_pop3Disconnect()
Voy a subir las librerías originales. Estas son _pop3.au3, _pop3_ampliado.au3, base64.au3. También subo un ejemplo.
SUBIDO EL NUEVO ARCHIVO CON EL NUEVO CÓDIGO DE LA LIBRERÍA _POP_AMPLIADO.AU3
Las direcciones url de los archivos, se encuentran en las explicaciones de las funciones.
Espero que os guste.
Saludos .