public override Indexable GetNextIndexable() { using (GMime.Message message = this.mbox_parser.ConstructMessage()) { // Work around what I think is a bug in GMime: If you // have a zero-byte file or seek to the end of a // file, parser.Eos () will return true until it // actually tries to read something off the wire. // Since parser.ConstructMessage() always returns a // message (which may also be a bug), we'll often get // one empty message which we need to deal with here. // // Check if its empty by seeing if the Headers // property is null or empty. if (message == null || message.Headers == null || message.Headers == "") { return(null); } ++this.count; string x_evolution = message.GetHeader("X-Evolution"); if (x_evolution == null || x_evolution == "") { Logger.Log.Info("{0}: Message at offset {1} has no X-Evolution header!", this.folder_name, this.mbox_parser.FromOffset); return(null); } // This extracts the UID and flags from the X-Evolution header. // It may also contain user-defined flags and tags, but we don't // support those right now. int separator_idx = x_evolution.IndexOf('-'); string uid_str = x_evolution.Substring(0, separator_idx); string uid = Convert.ToUInt32(uid_str, 16).ToString(); // ugh. uint flags = Convert.ToUInt32(x_evolution.Substring(separator_idx + 1, 4), 16); Indexable indexable = this.GMimeMessageToIndexable(uid, message, flags); if (Debug) { Logger.Log.Debug("Constructed message {0} with uid {1}, flags {2}. Indexable {3} null", this.count, uid, flags, indexable == null ? "" : "not"); } if (indexable == null) { return(null); } ++this.indexed_count; return(indexable); } }
/** * Create an indexable from an mbox message * Most of the code here is from Evo backend */ public Indexable MessageToIndexable(string file_name, System.Uri uri, GMime.Message message, string folder_name) { //Logger.Log.Debug ("Indexing " + uri + " in folder " + folder_name); Indexable indexable = new Indexable(uri); // set parent uri to the filename so that when an mbox file // is deleted, all the messages in that file can be deleted indexable.ParentUri = UriFu.PathToFileUri(file_name); indexable.Timestamp = message.Date.ToUniversalTime(); indexable.HitType = "MailMessage"; indexable.MimeType = "message/rfc822"; indexable.CacheContent = true; indexable.AddProperty(Property.NewUnsearched("fixme:client", "kmail")); indexable.AddProperty(Property.NewUnsearched("fixme:account", account_name)); indexable.AddProperty(Property.NewUnsearched("fixme:folder", folder_name)); GMime.InternetAddressList addrs; if (folder_name == Queryable.SentMailFolderName) { addrs = message.GetRecipients(GMime.RecipientType.To); foreach (GMime.InternetAddress ia in addrs) { if (ia is GMime.InternetAddressMailbox) { GMime.InternetAddressMailbox mailbox = ia as GMime.InternetAddressMailbox; indexable.AddProperty(Property.NewKeyword("fixme:sentTo", mailbox.Address)); } } addrs.Dispose(); } if (folder_name == Queryable.SentMailFolderName) { addrs = message.GetRecipients(GMime.RecipientType.Cc); foreach (GMime.InternetAddress ia in addrs) { if (ia is GMime.InternetAddressMailbox) { GMime.InternetAddressMailbox mailbox = ia as GMime.InternetAddressMailbox; indexable.AddProperty(Property.NewKeyword("fixme:sentTo", mailbox.Address)); } } addrs.Dispose(); } if (folder_name != Queryable.SentMailFolderName) { addrs = GMime.InternetAddressList.Parse(message.Sender); foreach (GMime.InternetAddress ia in addrs) { if (ia is GMime.InternetAddressMailbox) { GMime.InternetAddressMailbox mailbox = ia as GMime.InternetAddressMailbox; indexable.AddProperty(Property.NewKeyword("fixme:gotFrom", mailbox.Address)); } } addrs.Dispose(); } if (folder_name == Queryable.SentMailFolderName) { indexable.AddProperty(Property.NewFlag("fixme:isSent")); } else { string kmail_msg_sent = message.GetHeader("X-KMail-Link-Type"); if (kmail_msg_sent == "reply") { indexable.AddProperty(Property.NewFlag("fixme:isSent")); } } // no need to store date again, use the issent flag to determine if the date is sentdate or not #if false if (folder_name == Queryable.SentMailFolderName) { indexable.AddProperty(Property.NewDate("fixme:sentdate", message.Date.ToUniversalTime())); } else { indexable.AddProperty(Property.NewDate("fixme:received", message.Date.ToUniversalTime())); } #endif indexable.SetBinaryStream(message.Stream); return(indexable); }
// Copied from FilterMail.cs:DoPullProperties private Hit MessageToHit(GMime.Message message) { string msgid = message.GetHeader("Message-Id"); if (msgid == null) { return(null); } msgid = GMime.Utils.DecodeMessageId(msgid); Hit hit = new Hit(); hit.Uri = new Uri(String.Format(GMAIL_HIT_URL, domain, msgid)); hit.AddProperty(Property.NewUnsearched("beagle:HitType", "MailMessage")); hit.AddProperty(Property.NewUnsearched("beagle:MimeType", "text/html")); hit.AddProperty(Property.NewUnsearched("beagle:Source", "GMailSearch")); hit.Score = 1.0; hit.AddProperty(Property.NewUnsearched("fixme:msgid", msgid)); string subject = GMime.Utils.HeaderDecodePhrase(message.Subject); hit.AddProperty(Property.New("dc:title", subject)); hit.Timestamp = message.Date.ToUniversalTime(); hit.AddProperty(Property.NewDate("fixme:date", message.Date.ToUniversalTime())); GMime.InternetAddressList addrs; addrs = message.GetRecipients(GMime.RecipientType.To); foreach (GMime.InternetAddress ia in addrs) { hit.AddProperty(Property.NewUnsearched("fixme:to", ia.ToString(false))); if (ia is GMime.InternetAddressMailbox) { GMime.InternetAddressMailbox mailbox = ia as GMime.InternetAddressMailbox; hit.AddProperty(Property.New("fixme:to_address", mailbox.Address)); } hit.AddProperty(Property.New("fixme:to_name", ia.Name)); } addrs.Dispose(); addrs = message.GetRecipients(GMime.RecipientType.Cc); foreach (GMime.InternetAddress ia in addrs) { hit.AddProperty(Property.NewUnsearched("fixme:cc", ia.ToString(false))); if (ia is GMime.InternetAddressMailbox) { GMime.InternetAddressMailbox mailbox = ia as GMime.InternetAddressMailbox; hit.AddProperty(Property.New("fixme:cc_address", mailbox.Address)); } hit.AddProperty(Property.New("fixme:cc_name", ia.Name)); } addrs.Dispose(); addrs = GMime.InternetAddressList.Parse(message.Sender); foreach (GMime.InternetAddress ia in addrs) { hit.AddProperty(Property.NewUnsearched("fixme:from", ia.ToString(false))); if (ia is GMime.InternetAddressMailbox) { GMime.InternetAddressMailbox mailbox = ia as GMime.InternetAddressMailbox; hit.AddProperty(Property.New("fixme:from_address", mailbox.Address)); } hit.AddProperty(Property.New("fixme:from_name", ia.Name)); } addrs.Dispose(); foreach (GMime.References refs in message.References) { hit.AddProperty(Property.NewUnsearched("fixme:reference", refs.MessageId)); } string list_id = message.GetHeader("List-Id"); if (list_id != null) { hit.AddProperty(Property.New("fixme:mlist", GMime.Utils.HeaderDecodePhrase(list_id))); } return(hit); }