Imap support in util/evolution/camel.cs



Hi all.

When on a 3.5 hours flight across half of Australia, it's a perfect time
to hack on dashboard.

I added support for the Imap summary files to camel.cs.  This means that
it's possible to use your imap inbox as a source of information from the
Evolution backend.

Attached are three patches.

camel_imap_support.patch is the patch to camel.cs to get imap support
into it.  It changed a little bit how you should use this.  

EvolutionMailBackend.patch is a patch to EvolutionMailBackend to use the
new camel.cs.  It doesn't change the behaviour of it in any other
sense.  It still uses the MBox Inbox.

EvolutionMailBackend_imap_hardcoded.patch is how I've hardcoded my imap
inbox instead of the mbox inbox on my system.

camel.cs doesn't automatically see if it's a imap summary or a mbox
summary so you have to call it with 

Camel.Summary s = new Camel.MBoxSummary(path)

or 

Camel.Summary s = new Camel.ImapSummary(path)

This could probably be done better.

This is also only done for evolution 1.4.  I believe the format has
changed in evolution 1.5 but it should be quite simple to change this
code. I can probably do that once I start to use 1.5.

Also, this is among the first things I've seriously written in c# so
feel free to comment and call me an idiot for stupid programing :)

Regards,
Erik
Index: camel.cs
===================================================================
RCS file: /cvs/gnome/dashboard/util/evolution/camel.cs,v
retrieving revision 1.1
diff -u -r1.1 camel.cs
--- camel.cs	25 Jul 2003 10:02:38 -0000	1.1
+++ camel.cs	3 Mar 2004 00:56:56 -0000
@@ -3,6 +3,9 @@
 //
 // Authors:
 //    Miguel de Icaza <miguel ximian com>
+//
+//    Imap support by Erik Bågfors <erik bagfors nu>
+//
 
 using System.IO;
 using System;
@@ -10,11 +13,13 @@
 using System.Text;
 
 namespace Camel {
-	public class Summary {
-		public MBoxSummaryHeader header;
-		public MessageInfo [] messages;
-		
-		public Summary (string file)
+        public class Summary { 
+	    public SummaryHeader header;
+	    public MessageInfo [] messages;
+	}
+
+	public class MBoxSummary: Summary {
+		public MBoxSummary (string file)
 		{
 			using (FileStream f = File.OpenRead (file)){
 				header = new MBoxSummaryHeader (f);
@@ -28,6 +33,21 @@
 		}
 	}
 
+	public class ImapSummary: Summary {
+		public ImapSummary (string file)
+		{
+			using (FileStream f = File.OpenRead (file)){
+				header = new ImapSummaryHeader (f);
+
+				messages = new MessageInfo [header.count];
+				
+				for (int i = 0; i < header.count; i++){
+					messages [i] = new ImapMessageInfo (f);
+				}
+			}
+		}
+	}
+
 	public class MessageInfo {
 		public string uid, subject, from, to, cc, mlist;
 		public uint size, flags;
@@ -98,6 +118,80 @@
 					      from_pos, size);
 		}
 	}
+
+
+
+	public class ImapMessageInfo : MessageInfo {
+		uint server_flags;
+		
+		public ImapMessageInfo (FileStream f) : base (f)
+		{
+			server_flags = Decode.UInt (f);
+			PerformContentInfoLoad (f);
+		}
+
+		public override string ToString ()
+		{
+			return String.Format ("From: {0}\nTo: {1}\nSubject: {2}\nSize: {3}\n", from, to, subject, size);
+		}
+
+		private bool PerformContentInfoLoad (FileStream f)
+		{
+		    bool ci = ContentInfoLoad (f);
+		    if (!ci) 
+			return false;
+
+		    uint count = Decode.UInt (f);
+		    if (count == -1 || count > 500) {
+			return false;
+		    }
+		    
+		    for (int i = 0; i < count; i++) {
+
+			bool part = PerformContentInfoLoad (f);
+			if (!part) 
+			    throw new Exception ();
+		    }
+		    return true;
+		}
+
+		private bool ContentInfoLoad (FileStream f)
+		{
+		    string token;
+
+		    if (f.ReadByte () == 0) 
+			return true;
+
+		    // type
+		    token = Decode.Token (f);
+		    // subtype
+		    token = Decode.Token (f);
+
+		    uint count;
+		    count = Decode.UInt (f);
+		    if (count == -1 || count > 500)
+			return false;
+		    for (int i = 0; i < count; i++) {
+			// Name
+			token = Decode.Token (f);
+			// Value
+			token = Decode.Token (f);
+		    }
+		    
+		    // id
+		    token = Decode.Token (f);
+
+		    // description
+		    token = Decode.Token (f);
+
+		    // encoding
+		    token = Decode.Token (f);
+
+		    // size
+		    Decode.UInt (f);
+		    return true;
+		}
+	}
 	
 	public class SummaryHeader {
 		public int      version;
@@ -127,6 +221,15 @@
 			Console.WriteLine ("Folder size:" + folder_size);
 		}
 	}
+
+	public class ImapSummaryHeader : SummaryHeader {
+		public uint validity;
+		
+		public ImapSummaryHeader (FileStream f) : base (f)
+		{
+			validity = Decode.UInt (f);
+		}
+	}
 	
 	public class Decode {
 		static Encoding e = Encoding.UTF8;
@@ -136,6 +239,25 @@
 		{
 			UnixBaseTicks = new DateTime (1970, 1, 1, 0, 0, 0).Ticks;
 		}
+
+		public static string Token (FileStream f) 
+		{
+		    int len = (int) UInt (f);
+		    if (len < 32) {
+			if (len <= 0) 
+			    return "NULL"; 
+			
+			// Ok, this is a token from the list, we can ignore it
+			return "token_from_list";
+		    } else if (len > 10240) {
+			throw new Exception ();
+		    } else {
+			len -= 32;
+			byte [] buffer = new byte [len];
+			f.Read (buffer, 0, (int) len);
+			return new System.String (e.GetChars (buffer, 0, len));
+		    }
+		}
 	       
 		public static string String (FileStream f)
 		{
@@ -195,11 +317,16 @@
 			string file;
 			
 			if (args.Length == 0)
-				file = "mbox.ev-summary";
+			//	file = "mbox.ev-summary";
+				file = "summary";
 			else
 				file = args [0];
 			
-			Summary s = new Summary (file);
+			//Summary s = new MBoxSummary("mbox.ev-summary");
+			Summary s = new ImapSummary(file);
+			for (int i = 0; i < s.header.count; i++) {
+			    Console.WriteLine(s.messages [i]);
+			}
 			
 		}
 		
Index: EvolutionMailBackend.cs
===================================================================
RCS file: /cvs/gnome/dashboard/backends/EvolutionMailBackend.cs,v
retrieving revision 1.19
diff -u -r1.19 EvolutionMailBackend.cs
--- EvolutionMailBackend.cs	2 Mar 2004 04:27:01 -0000	1.19
+++ EvolutionMailBackend.cs	3 Mar 2004 01:05:29 -0000
@@ -31,7 +31,7 @@
 				return false;
 
 			try {
-				summary = new Camel.Summary (summary_path);
+				summary = new Camel.MBoxSummary (summary_path);
 			} catch (Exception e) {
 				Console.WriteLine ("Could not load camel summary: " + summary_path + e);
 				return false;
@@ -75,7 +75,7 @@
 		{
 			ArrayList mails = new ArrayList ();
 
-			foreach (Camel.MBoxMessageInfo mi in summary.messages) {
+			foreach (Camel.MessageInfo mi in summary.messages) {
 
 				if (mi.from.IndexOf (text) == -1)
 					continue;
@@ -91,7 +91,7 @@
 		{
 			ArrayList matches = new ArrayList();
 
-			foreach (Camel.MBoxMessageInfo mi in mails) {
+			foreach (Camel.MessageInfo mi in mails) {
 					Match match = new Match ("MailMessage", clue);
 					match ["Icon"]     = "internal:mail.png";
 					match ["Title"]    = mi.subject;
Index: EvolutionMailBackend.cs
===================================================================
RCS file: /cvs/gnome/dashboard/backends/EvolutionMailBackend.cs,v
retrieving revision 1.19
diff -u -r1.19 EvolutionMailBackend.cs
--- EvolutionMailBackend.cs	2 Mar 2004 04:27:01 -0000	1.19
+++ EvolutionMailBackend.cs	3 Mar 2004 01:03:00 -0000
@@ -26,12 +26,13 @@
 		{
 			Name = "Evolution Mail";
 
-			summary_path = GetDefaultMailSummaryPath ();
+			//summary_path = GetDefaultMailSummaryPath ();
+			summary_path = "/home/bagfors/evolution/mail/imap/bagfors localhost:1143/folders/INBOX/summary"; 
 			if (summary_path == null)
 				return false;
 
 			try {
-				summary = new Camel.Summary (summary_path);
+				summary = new Camel.ImapSummary (summary_path);
 			} catch (Exception e) {
 				Console.WriteLine ("Could not load camel summary: " + summary_path + e);
 				return false;
@@ -75,7 +76,7 @@
 		{
 			ArrayList mails = new ArrayList ();
 
-			foreach (Camel.MBoxMessageInfo mi in summary.messages) {
+			foreach (Camel.MessageInfo mi in summary.messages) {
 
 				if (mi.from.IndexOf (text) == -1)
 					continue;
@@ -91,7 +92,7 @@
 		{
 			ArrayList matches = new ArrayList();
 
-			foreach (Camel.MBoxMessageInfo mi in mails) {
+			foreach (Camel.MessageInfo mi in mails) {
 					Match match = new Match ("MailMessage", clue);
 					match ["Icon"]     = "internal:mail.png";
 					match ["Title"]    = mi.subject;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]