Przeglądaj źródła

Add expunge, flags, append

Pascal Peridont 19 lat temu
rodzic
commit
f5a2d2ee77
1 zmienionych plików z 71 dodań i 19 usunięć
  1. 71 19
      std/mtwin/mail/Imap.hx

+ 71 - 19
std/mtwin/mail/Imap.hx

@@ -29,20 +29,22 @@ import mtwin.mail.Exception;
 
 signature ImapMailbox = {
 	name: String,
-	flags: List<String>,
+	flags: ImapFlags,
 	hasChildren: Bool
 }
 
 signature ImapFetchResponse = {
 	bodyType: String,
 	body: String,
-	flags: List<String>,
+	flags: ImapFlags,
 	uid: Int,
 	structure: ImapBodyStructure,
 	internalDate: String,
 	envelope: ImapEnvelope
 }
 
+signature ImapFlags = Array<String>
+
 enum ImapSection {
 	Flags;
 	Uid;
@@ -66,6 +68,12 @@ enum ImapRange {
 	Composite(l:Array<ImapRange>);
 }
 
+enum ImapFlagMode {
+	Add;
+	Remove;
+	Replace;
+}
+
 class Imap {
 	public static var DEBUG = false;
 	public static var TIMEOUT = 5;
@@ -128,7 +136,7 @@ class Imap {
 		Login to server
 	**/
 	public function login( user : String, pass : String ){	
-		var r = command("LOGIN",user+" "+pass,true);
+		var r = command("LOGIN",user+" "+pass);
 		if( !r.success ){
 			throw BadResponse(r.response);
 		}
@@ -148,9 +156,9 @@ class Imap {
 	public function mailboxes( ?pattern : String ) : List<ImapMailbox> {
 		var r;
 		if( pattern == null ){
-			r = command("LIST","\".\" \"*\"",true);
+			r = command("LIST","\".\" \"*\"");
 		}else{
-			r = command("LIST","\".\" \""+pattern+"\"",true);
+			r = command("LIST","\".\" \""+pattern+"\"");
 		}
 		if( !r.success ){
 			throw BadResponse(r.response);
@@ -162,18 +170,14 @@ class Imap {
 				var name = REG_LIST_RESP.matched(2);
 				var flags = REG_LIST_RESP.matched(1).split(" ");
 
-				var t = {name: name,flags: new List(),hasChildren: false};
+				var t = {name: name,flags: flags,hasChildren: false};
 
 				for( v in flags ){
-					if( v == "" ) continue;
-					
 					if( v == "\\HasNoChildren" ){
 						t.hasChildren = false;
 					}else if( v == "\\HasChildren" ){
 						t.hasChildren = true;
 					}
-
-					t.flags.add( v );
 				}
 
 				ret.add(t);
@@ -186,7 +190,7 @@ class Imap {
 		Select a mailbox
 	**/
 	public function select( mailbox : String ){
-		var r = command("SELECT",quote(mailbox),true);
+		var r = command("SELECT",quote(mailbox));
 		if( !r.success ) 
 			throw BadResponse(r.response);
 		
@@ -205,11 +209,11 @@ class Imap {
 	}
 
 	/**
-		Search for messages. Pattern syntax described in RFC 2060, section 6.4.4
+		Search for messages. Pattern syntax described in RFC 3501, section 6.4.4
 	**/
 	public function search( ?pattern : String ){
 		if( pattern == null ) pattern = "ALL";
-		var r = command("SEARCH",pattern,true);
+		var r = command("SEARCH",pattern);
 		if( !r.success ){
 			throw BadResponse(r.response);
 		}
@@ -345,6 +349,54 @@ class Imap {
 		return ret;
 	}
 
+	public function append( mailbox : String, msg : String, ?flags : ImapFlags ){
+		var f = if( flags != null ) "("+flags.join(" ")+") " else "";
+		command("APPEND",quote(mailbox)+" "+f+"{"+msg.length+"}",false);
+		cnx.write( msg );
+		cnx.write( "\r\n" );
+		var r = read( StringTools.lpad(Std.string(count),"A000",4) );
+		if( !r.success )
+			throw BadResponse(r.response);
+	}
+
+	public function expunge(){
+		var r = command("EXPUNGE");
+		if( !r.success )
+			throw BadResponse(r.response);
+	}
+
+	public function flags( iRange : ImapRange, flags : ImapFlags, ?mode : ImapFlagMode, ?fetchResult : Bool ) : IntHash<Array<String>> {
+		if( mode == null ) mode = Add;
+		if( fetchResult == null ) fetchResult = false;
+		
+		var range = Tools.imapRangeString(iRange);
+		var elem = switch( mode ){
+			case Add: "+FLAGS";
+			case Remove: "-FLAGS";
+			case Replace: "FLAGS";
+		}
+		if( !fetchResult ){
+			elem += ".SILENT";
+		}
+
+		var r = command( "STORE", range + " " + elem + "("+flags.join(" ")+")");
+		if( !r.success ) throw BadResponse( r.response );
+		if( !fetchResult ) return null;
+
+		var ret = new IntHash();
+		for( line in r.result ){
+			if( REG_FETCH_MAIN.match(line) ){
+				var id = Std.parseInt(REG_FETCH_MAIN.matched(1));
+				if( REG_FETCH_FLAGS.match( REG_FETCH_MAIN.matchedRight() ) ){
+					ret.set(id,REG_FETCH_FLAGS.matched(1).split(" "));
+				}
+			}
+		}
+		return ret;
+	}
+
+	/////
+
 	function completeString( s ){
 		var reg = ~/(?<!\] )\{([0-9]+)\}$/;
 		while( reg.match( s ) ){
@@ -356,17 +408,17 @@ class Imap {
 		return s;
 	}
 
-	//
-
-	function command( command, args, r ){
+	function command( command : String, ?args : String , ?r : Bool ){
 		if( cnx == null )
 			throw NotConnected;
-
+		if( r == null ) r = true;
+		if( args == null ) args = "" else args = " "+args;
+		
 		count++;
 		var c = Std.string(count);
 		c = StringTools.lpad(c,"A000",4);
-		cnx.write( c+" "+command+" "+args+"\r\n" );
-		debug( "S: "+c+" "+command+" "+args );
+		cnx.write( c+" "+command+args+"\r\n" );
+		debug( "S: "+c+" "+command+args );
 
 		if( !r ){
 			return null;