Search in sources :

Example 1 with Pop3Message

use of com.zimbra.cs.pop3.Pop3Message in project zm-mailbox by Zimbra.

the class DbMailItem method loadPop3Folder.

public static List<Pop3Message> loadPop3Folder(Set<Folder> folders, Date popSince) throws ServiceException {
    assert !folders.isEmpty() : folders;
    Mailbox mbox = Iterables.get(folders, 0).getMailbox();
    long popDate = popSince == null ? -1 : Math.max(popSince.getTime(), -1);
    List<Pop3Message> result = new ArrayList<Pop3Message>();
    DbConnection conn = mbox.getOperationConnection();
    PreparedStatement stmt = null;
    ResultSet rs = null;
    try {
        String dateConstraint = popDate < 0 ? "" : " AND date > ?";
        stmt = conn.prepareStatement("SELECT mi.id, mi.size, mi.blob_digest FROM " + getMailItemTableName(mbox, " mi") + " WHERE " + IN_THIS_MAILBOX_AND + DbUtil.whereIn("folder_id", folders.size()) + " AND type = " + MailItem.Type.MESSAGE.toByte() + " AND " + Db.getInstance().bitAND("flags", String.valueOf(Flag.BITMASK_DELETED | Flag.BITMASK_POPPED)) + " = 0" + dateConstraint);
        if (getTotalFolderSize(folders) > RESULTS_STREAMING_MIN_ROWS) {
            //TODO: Because of POPPED flag, the folder size no longer represent the count.
            Db.getInstance().enableStreaming(stmt);
        }
        int pos = 1;
        pos = setMailboxId(stmt, mbox, pos);
        for (Folder folder : folders) {
            stmt.setInt(pos++, folder.getId());
        }
        if (popDate >= 0) {
            stmt.setInt(pos++, (int) (popDate / 1000L));
        }
        rs = stmt.executeQuery();
        while (rs.next()) {
            result.add(new Pop3Message(rs.getInt(1), rs.getLong(2), rs.getString(3)));
        }
        return result;
    } catch (SQLException e) {
        throw ServiceException.FAILURE("loading POP3 folder data: " + folders, e);
    } finally {
        DbPool.closeResults(rs);
        DbPool.closeStatement(stmt);
    }
}
Also used : Mailbox(com.zimbra.cs.mailbox.Mailbox) Pop3Message(com.zimbra.cs.pop3.Pop3Message) SQLException(java.sql.SQLException) ArrayList(java.util.ArrayList) ResultSet(java.sql.ResultSet) PreparedStatement(java.sql.PreparedStatement) Folder(com.zimbra.cs.mailbox.Folder) DbConnection(com.zimbra.cs.db.DbPool.DbConnection)

Example 2 with Pop3Message

use of com.zimbra.cs.pop3.Pop3Message in project zm-mailbox by Zimbra.

the class Mailbox method openPop3Folder.

public List<Pop3Message> openPop3Folder(OperationContext octxt, Set<Integer> folderIds, Date popSince) throws ServiceException {
    boolean success = false;
    try {
        beginTransaction("openPop3Folder", octxt);
        ImmutableSet.Builder<Folder> folders = ImmutableSet.builder();
        for (int folderId : folderIds) {
            folders.add(getFolderById(folderId));
        }
        List<Pop3Message> p3list = DbMailItem.loadPop3Folder(folders.build(), popSince);
        success = true;
        return p3list;
    } finally {
        endTransaction(success);
    }
}
Also used : ImmutableSet(com.google.common.collect.ImmutableSet) Pop3Message(com.zimbra.cs.pop3.Pop3Message) CreateFolder(com.zimbra.cs.redolog.op.CreateFolder) ZFolder(com.zimbra.client.ZFolder) RefreshMountpoint(com.zimbra.cs.redolog.op.RefreshMountpoint) TargetConstraint(com.zimbra.cs.mailbox.MailItem.TargetConstraint) CreateMountpoint(com.zimbra.cs.redolog.op.CreateMountpoint)

Example 3 with Pop3Message

use of com.zimbra.cs.pop3.Pop3Message in project k-9 by k9mail.

the class Pop3Sync method downloadLargeMessages.

private void downloadLargeMessages(final SyncConfig syncConfig, final Pop3Folder remoteFolder, final BackendFolder backendFolder, List<Pop3Message> largeMessages, final AtomicInteger progress, final AtomicInteger newMessages, final int todo, FetchProfile fp, SyncListener listener) throws MessagingException {
    final String folder = remoteFolder.getServerId();
    Timber.d("SYNC: Fetching large messages for folder %s", folder);
    int maxDownloadSize = syncConfig.getMaximumAutoDownloadMessageSize();
    remoteFolder.fetch(largeMessages, fp, null, maxDownloadSize);
    for (Pop3Message message : largeMessages) {
        downloadSaneBody(syncConfig, remoteFolder, backendFolder, message);
        String messageServerId = message.getUid();
        Timber.v("About to notify listeners that we got a new large message %s:%s:%s", accountName, folder, messageServerId);
        // Update the listener with what we've found
        progress.incrementAndGet();
        // TODO do we need to re-fetch this here?
        Set<Flag> flags = backendFolder.getMessageFlags(messageServerId);
        // not marked as read.
        if (!flags.contains(Flag.SEEN)) {
            newMessages.incrementAndGet();
        }
        listener.syncProgress(folder, progress.get(), todo);
        boolean isOldMessage = isOldMessage(backendFolder, message);
        listener.syncNewMessage(folder, messageServerId, isOldMessage);
    }
    Timber.d("SYNC: Done fetching large messages for folder %s", folder);
}
Also used : Pop3Message(com.fsck.k9.mail.store.pop3.Pop3Message) Flag(com.fsck.k9.mail.Flag)

Example 4 with Pop3Message

use of com.zimbra.cs.pop3.Pop3Message in project k-9 by k9mail.

the class Pop3Sync method downloadMessages.

private int downloadMessages(final SyncConfig syncConfig, final Pop3Folder remoteFolder, final BackendFolder backendFolder, List<Pop3Message> inputMessages, final SyncListener listener) throws MessagingException {
    final Date earliestDate = syncConfig.getEarliestPollDate();
    // now
    Date downloadStarted = new Date();
    if (earliestDate != null) {
        Timber.d("Only syncing messages after %s", earliestDate);
    }
    final String folder = remoteFolder.getServerId();
    List<Pop3Message> syncFlagMessages = new ArrayList<>();
    List<Pop3Message> unsyncedMessages = new ArrayList<>();
    final AtomicInteger newMessages = new AtomicInteger(0);
    List<Pop3Message> messages = new ArrayList<>(inputMessages);
    for (Pop3Message message : messages) {
        evaluateMessageForDownload(message, folder, backendFolder, unsyncedMessages, syncFlagMessages, listener);
    }
    final AtomicInteger progress = new AtomicInteger(0);
    final int todo = unsyncedMessages.size() + syncFlagMessages.size();
    listener.syncProgress(folder, progress.get(), todo);
    Timber.d("SYNC: Have %d unsynced messages", unsyncedMessages.size());
    messages.clear();
    final List<Pop3Message> largeMessages = new ArrayList<>();
    final List<Pop3Message> smallMessages = new ArrayList<>();
    if (!unsyncedMessages.isEmpty()) {
        int visibleLimit = backendFolder.getVisibleLimit();
        int listSize = unsyncedMessages.size();
        if ((visibleLimit > 0) && (listSize > visibleLimit)) {
            unsyncedMessages = unsyncedMessages.subList(0, visibleLimit);
        }
        FetchProfile fp = new FetchProfile();
        fp.add(FetchProfile.Item.ENVELOPE);
        Timber.d("SYNC: About to fetch %d unsynced messages for folder %s", unsyncedMessages.size(), folder);
        fetchUnsyncedMessages(syncConfig, remoteFolder, unsyncedMessages, smallMessages, largeMessages, progress, todo, fp, listener);
        Timber.d("SYNC: Synced unsynced messages for folder %s", folder);
    }
    Timber.d("SYNC: Have %d large messages and %d small messages out of %d unsynced messages", largeMessages.size(), smallMessages.size(), unsyncedMessages.size());
    unsyncedMessages.clear();
    /*
         * Grab the content of the small messages first. This is going to
         * be very fast and at very worst will be a single up of a few bytes and a single
         * download of 625k.
         */
    FetchProfile fp = new FetchProfile();
    // TODO: Only fetch small and large messages if we have some
    fp.add(FetchProfile.Item.BODY);
    // fp.add(FetchProfile.Item.FLAGS);
    // fp.add(FetchProfile.Item.ENVELOPE);
    downloadSmallMessages(remoteFolder, backendFolder, smallMessages, progress, newMessages, todo, fp, listener);
    smallMessages.clear();
    /*
         * Now do the large messages that require more round trips.
         */
    fp = new FetchProfile();
    fp.add(FetchProfile.Item.STRUCTURE);
    downloadLargeMessages(syncConfig, remoteFolder, backendFolder, largeMessages, progress, newMessages, todo, fp, listener);
    largeMessages.clear();
    Timber.d("SYNC: Synced remote messages for folder %s, %d new messages", folder, newMessages.get());
    // If the oldest message seen on this sync is newer than the oldest message seen on the previous sync, then
    // we want to move our high-water mark forward.
    Date oldestMessageTime = backendFolder.getOldestMessageDate();
    if (oldestMessageTime != null) {
        if (oldestMessageTime.before(downloadStarted) && oldestMessageTime.after(getLatestOldMessageSeenTime(backendFolder))) {
            setLatestOldMessageSeenTime(backendFolder, oldestMessageTime);
        }
    }
    return newMessages.get();
}
Also used : FetchProfile(com.fsck.k9.mail.FetchProfile) Pop3Message(com.fsck.k9.mail.store.pop3.Pop3Message) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) ArrayList(java.util.ArrayList) Date(java.util.Date)

Example 5 with Pop3Message

use of com.zimbra.cs.pop3.Pop3Message in project k-9 by k9mail.

the class Pop3Sync method fetchUnsyncedMessages.

private void fetchUnsyncedMessages(final SyncConfig syncConfig, final Pop3Folder remoteFolder, List<Pop3Message> unsyncedMessages, final List<Pop3Message> smallMessages, final List<Pop3Message> largeMessages, final AtomicInteger progress, final int todo, FetchProfile fp, final SyncListener listener) throws MessagingException {
    final String folder = remoteFolder.getServerId();
    final Date earliestDate = syncConfig.getEarliestPollDate();
    remoteFolder.fetch(unsyncedMessages, fp, new MessageRetrievalListener<Pop3Message>() {

        @Override
        public void messageFinished(Pop3Message message, int number, int ofTotal) {
            try {
                if (message.isSet(Flag.DELETED) || message.olderThan(earliestDate)) {
                    if (message.isSet(Flag.DELETED)) {
                        Timber.v("Newly downloaded message %s:%s:%s was marked deleted on server, " + "skipping", accountName, folder, message.getUid());
                    } else {
                        Timber.d("Newly downloaded message %s is older than %s, skipping", message.getUid(), earliestDate);
                    }
                    progress.incrementAndGet();
                    // TODO: This might be the source of poll count errors in the UI. Is todo always the same as ofTotal
                    listener.syncProgress(folder, progress.get(), todo);
                    return;
                }
                if (syncConfig.getMaximumAutoDownloadMessageSize() > 0 && message.getSize() > syncConfig.getMaximumAutoDownloadMessageSize()) {
                    largeMessages.add(message);
                } else {
                    smallMessages.add(message);
                }
            } catch (Exception e) {
                Timber.e(e, "Error while storing downloaded message.");
            }
        }

        @Override
        public void messageStarted(String uid, int number, int ofTotal) {
        }

        @Override
        public void messagesFinished(int total) {
        // FIXME this method is almost never invoked by various Stores! Don't rely on it unless fixed!!
        }
    }, syncConfig.getMaximumAutoDownloadMessageSize());
}
Also used : Pop3Message(com.fsck.k9.mail.store.pop3.Pop3Message) Date(java.util.Date) MessagingException(com.fsck.k9.mail.MessagingException) AuthenticationFailedException(com.fsck.k9.mail.AuthenticationFailedException)

Aggregations

Pop3Message (com.fsck.k9.mail.store.pop3.Pop3Message)5 ArrayList (java.util.ArrayList)4 Date (java.util.Date)3 AuthenticationFailedException (com.fsck.k9.mail.AuthenticationFailedException)2 MessagingException (com.fsck.k9.mail.MessagingException)2 Pop3Folder (com.fsck.k9.mail.store.pop3.Pop3Folder)2 Pop3Message (com.zimbra.cs.pop3.Pop3Message)2 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)2 BackendFolder (com.fsck.k9.backend.api.BackendFolder)1 MoreMessages (com.fsck.k9.backend.api.BackendFolder.MoreMessages)1 FetchProfile (com.fsck.k9.mail.FetchProfile)1 Flag (com.fsck.k9.mail.Flag)1 ImmutableSet (com.google.common.collect.ImmutableSet)1 ZFolder (com.zimbra.client.ZFolder)1 DbConnection (com.zimbra.cs.db.DbPool.DbConnection)1 Folder (com.zimbra.cs.mailbox.Folder)1 TargetConstraint (com.zimbra.cs.mailbox.MailItem.TargetConstraint)1 Mailbox (com.zimbra.cs.mailbox.Mailbox)1 CreateFolder (com.zimbra.cs.redolog.op.CreateFolder)1 CreateMountpoint (com.zimbra.cs.redolog.op.CreateMountpoint)1