Example #1
0
        public async Task OpenAttachmentAsync(MailMessage message, Attachment attachment)
        {
            // Lazy load
            if (attachment.Scope < Scope.HeadersAndBody)
            {
                // Check local storage
                if (MailStorage.HasMessagePart(message.GetThreadId(), message.GetMessageId(), attachment.BodyId))
                {
                    // TODO: Can we open the attachment directly from isolated storage?
                    attachment.Body = await MailStorage.GetMessagePartAsync(message.GetThreadId(), message.GetMessageId(), attachment.BodyId);
                }
                else
                {
                    // Download from the network
                    await GmailImap.GetBodyPartAsync(message.Uid, attachment, async() =>
                    {
                        if (ActiveLabel.Info.StoreMessages && ActiveLabel.Info.StoreAttachments)
                        {
                            await MailStorage.StoreMessagePartAsync(message.GetThreadId(), message.GetMessageId(), attachment.BodyId, attachment.Body);
                        }
                    }, CancellationToken.None);
                }
            }

            StorageFile file = await MailStorage.SaveAttachmentToTempAsync(attachment);

            // http://architects.dzone.com/articles/lap-around-windows-phone-8-sdk
            await Launcher.LaunchFileAsync(file);

            // TODO: Delete temp files on app close?
        }
Example #2
0
 public virtual async Task LazyLoadBodyPartAsync(MailMessage message, ObjectWHeaders part)
 {
     if (part.Scope < Scope.HeadersAndBody)
     {
         if (MailStorage.HasMessagePart(message.GetThreadId(), message.GetMessageId(), part.BodyId))
         {
             part.Body = await MailStorage.GetMessagePartAsync(message.GetThreadId(), message.GetMessageId(), part.BodyId);
         }
         else
         {
             await GmailImap.GetBodyPartAsync(message.Uid, part, async() =>
             {
                 if (ActiveLabel.Info.StoreMessages)
                 {
                     await MailStorage.StoreMessagePartAsync(message.GetThreadId(), message.GetMessageId(), part.BodyId, part.Body);
                 }
             }, CancellationToken.None);
         }
     }
 }
Example #3
0
        // Examine the local data store to see if there are any attachment bodies that still need to be downloaded.
        public async Task SyncAttachmentsAsync(CancellationToken cancellationToken)
        {
            List <MessageIdInfo> localIds = await MailStorage.GetLabelMessageListAsync(ActiveLabel.Info.Name) ?? new List <MessageIdInfo>();

            List <KeyValuePair <MessageIdInfo, ObjectWHeaders> > attachmentsToDownload = new List <KeyValuePair <MessageIdInfo, ObjectWHeaders> >();

            foreach (MessageIdInfo ids in localIds)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                MailMessage headers = await MailStorage.GetMessageHeadersAsync(ids.ThreadId, ids.MessageId);

                if (headers == null)
                {
                    // Downloading headers should have happened elsewhere.
                    continue;
                }

                if (headers.HasMutipartBody)
                {
                    foreach (Attachment attachment in headers.Attachments)
                    {
                        if (!MailStorage.HasMessagePart(ids.ThreadId, ids.MessageId, attachment.BodyId))
                        {
                            attachmentsToDownload.Add(new KeyValuePair <MessageIdInfo, ObjectWHeaders>(ids, attachment));
                        }
                    }
                }
            }

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            // TODO: Batch by bodyId?
            foreach (var pair in attachmentsToDownload)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                // TODO: Consider streaming the body directly to disk.  Even more so for attachments.
                await GmailImap.GetBodyPartAsync(pair.Key.Uid, pair.Value,
                                                 async() =>
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    await MailStorage.StoreMessagePartAsync(pair.Key.ThreadId, pair.Key.MessageId, pair.Value.BodyId, pair.Value.Body);

                    // Release the body for GC. Otherwise the bodiesToDownload list will keep everything im memory.
                    pair.Value.Body = null;
                }, cancellationToken);
            }
        }
Example #4
0
        // Examine the local data store to see if there are any message bodies that still need to be downloaded.
        public async Task SyncMessageBodiesAsync(CancellationToken cancellationToken)
        {
            List <MessageIdInfo> localIds = await MailStorage.GetLabelMessageListAsync(ActiveLabel.Info.Name) ?? new List <MessageIdInfo>();

            List <KeyValuePair <MessageIdInfo, ObjectWHeaders> > bodiesToDownload = new List <KeyValuePair <MessageIdInfo, ObjectWHeaders> >();

            foreach (MessageIdInfo ids in localIds)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                MailMessage headers = await MailStorage.GetMessageHeadersAsync(ids.ThreadId, ids.MessageId);

                if (headers == null)
                {
                    // Downloading headers should have happened elsewhere.
                    continue;
                }

                if (headers.HasMutipartBody)
                {
                    foreach (Attachment view in headers.AlternateViews)
                    {
                        if (!MailStorage.HasMessagePart(ids.ThreadId, ids.MessageId, view.BodyId))
                        {
                            bodiesToDownload.Add(new KeyValuePair <MessageIdInfo, ObjectWHeaders>(ids, view));
                        }
                    }
                    // Attachments will be downloaded seperately as well.
                    // TODO: but maybe we could build the list here while we're looking?
                }
                else
                {
                    // Primary body, no attachments or alternate views
                    if (!MailStorage.HasMessagePart(ids.ThreadId, ids.MessageId, headers.BodyId))
                    {
                        bodiesToDownload.Add(new KeyValuePair <MessageIdInfo, ObjectWHeaders>(ids, headers));
                    }
                }
            }

            if (cancellationToken.IsCancellationRequested)
            {
                return;
            }

            // TODO: Batch
            foreach (var pair in bodiesToDownload)
            {
                if (cancellationToken.IsCancellationRequested)
                {
                    return;
                }

                // TODO: Consider only downloading the first X bytes of each message, and loading more only on demand.
                // TODO: Consider streaming the body directly to disk.  Even more so for attachments.
                await GmailImap.GetBodyPartAsync(pair.Key.Uid, pair.Value,
                                                 async() =>
                {
                    if (cancellationToken.IsCancellationRequested)
                    {
                        return;
                    }

                    await MailStorage.StoreMessagePartAsync(pair.Key.ThreadId, pair.Key.MessageId, pair.Value.BodyId, pair.Value.Body);

                    // Release the body for GC. Otherwise the bodiesToDownload list will keep everything im memory.
                    pair.Value.Body = null;
                }, cancellationToken);
            }
        }