From 06aa753d873fe0a8be781206427d9ebfdc166317 Mon Sep 17 00:00:00 2001 From: Jamie Cameron Date: Sat, 21 Jul 2007 22:13:43 +0000 Subject: [PATCH] Completed new index design and UI re-coding --- mailboxes/boxes-lib.pl | 4 +- mailboxes/folders-lib.pl | 91 +++++++++++++++++++++------------------- mailboxes/lang/en | 13 ++++-- 3 files changed, 61 insertions(+), 47 deletions(-) diff --git a/mailboxes/boxes-lib.pl b/mailboxes/boxes-lib.pl index 6ea2b69fa..0bc828bef 100644 --- a/mailboxes/boxes-lib.pl +++ b/mailboxes/boxes-lib.pl @@ -82,7 +82,7 @@ foreach my $i (@$ids) { local $ll = ; local $fromok = $ll !~ /^From\s+(\S+).*\d+\r?\n/ || ($1 eq '-' && !$dash) ? 0 : 1; - print STDERR "seeking to $pos in $umf, got $ll"; + print DEBUG "seeking to $pos in $umf, got $ll"; if (!$fromok) { # Oh noes! Need to find it if (!$gotindex++) { @@ -239,7 +239,7 @@ if (open(IDSFILE, $idsfile)) { if (scalar(@ids) != $index->{'mailcount'}) { # Build for first time - print STDERR "need meta-index rebuild for $_[0] ",scalar(@ids)," != ",$index->{'mailcount'},"\n"; + print DEBUG "need meta-index rebuild for $_[0] ",scalar(@ids)," != ",$index->{'mailcount'},"\n"; @ids = ( ); while(my ($k, $v) = each %$index) { if ($k eq int($k) && $k < $index->{'mailcount'}) { diff --git a/mailboxes/folders-lib.pl b/mailboxes/folders-lib.pl index 182219098..fa9a08786 100644 --- a/mailboxes/folders-lib.pl +++ b/mailboxes/folders-lib.pl @@ -196,7 +196,7 @@ elsif ($_[2]->{'type'} == 5) { # Work out exactly how big the total is local ($sf, %len, $count); foreach $sf (@{$_[2]->{'subfolders'}}) { - print STDERR "working out size of ",&folder_name($sf),"\n"; + print DEBUG "working out size of ",&folder_name($sf),"\n"; $len{$sf} = &mailbox_folder_size($sf); $count += $len{$sf}; } @@ -215,7 +215,7 @@ elsif ($_[2]->{'type'} == 5) { $sfstart >= $len{$sf} ? $len{$sf}-1 : $sfstart; $sfend = $sfend < 0 ? 0 : $sfend >= $len{$sf} ? $len{$sf}-1 : $sfend; - print STDERR "getting mail from $sfstart to $sfend in $sfn\n"; + print DEBUG "getting mail from $sfstart to $sfend in $sfn\n"; local @submail = &mailbox_list_mails($sfstart, $sfend, $sf, $_[3]); local $sm; @@ -327,7 +327,7 @@ elsif ($folder->{'type'} == 2) { # For each requested uidl, get the headers or body foreach my $i (@$ids) { local $u = &safe_uidl($i); - print STDERR "need uidl $i -> $uidlmap{$i}\n"; + print DEBUG "need uidl $i -> $uidlmap{$i}\n"; if ($cached{$u} == 2 || $cached{$u} == 1 && $headersonly) { # We already have everything that we need } @@ -418,28 +418,35 @@ elsif ($folder->{'type'} == 4) { $wantpos{$ids->[$i]} = $i; } - # Fetch each mail by ID + # Fetch each mail by ID. This is done in blocks of 1000, to avoid + # hitting a the IMAP server's max request limit local @rv = map { undef } @$ids; local $wanted = $headersonly ? "(RFC822.SIZE UID RFC822.HEADER)" : "(UID RFC822)"; if (@$ids) { - local @idxrv = &imap_command($h, - "UID FETCH ".join(",", @$ids)." $wanted"); - foreach my $idxrv (@{idxrv->[1]}) { - local $mail = &parse_imap_mail($idxrv); - if ($mail) { - $mail->{'idx'} = $mail->{'imapidx'}; - $rv[$wantpos{$mail->{'id'}}] = $mail; + for(my $chunk=0; $chunk<@$ids; $chunk+=1000) { + local $chunkend = $chunk+999; + if ($chunkend >= @$ids) { $chunkend = @$ids-1; } + local @cids = @$ids[$chunk .. $chunkend]; + local @idxrv = &imap_command($h, + "UID FETCH ".join(",", @cids)." $wanted"); + foreach my $idxrv (@{idxrv->[1]}) { + local $mail = &parse_imap_mail($idxrv); + if ($mail) { + $mail->{'idx'} = $mail->{'imapidx'}-1; + $rv[$wantpos{$mail->{'id'}}] = $mail; + } } } } + print DEBUG "imap rv = ",scalar(@rv),"\n"; return @rv; } elsif ($folder->{'type'} == 5 || $folder->{'type'} == 6) { # Virtual or composite folder .. for each ID, work out the folder and # build a map from folders to ID lists - print STDERR "selecting ",scalar(@$ids)," ids\n"; + print DEBUG "selecting ",scalar(@$ids)," ids\n"; # Build a map from sub-folder names to IDs in them my $i = 0; @@ -485,7 +492,7 @@ elsif ($folder->{'type'} == 5 || $folder->{'type'} == 6) { $sfn."\t".$sfmail[$i]->{'id'}; $sfmail[$i]->{'idx'} = &indexof( $sfmail[$i]->{'id'}, @allids); - print STDERR "looking for ",$sfmail[$i]->{'id'}," found at ",$sfmail[$i]->{'idx'},"\n"; + print DEBUG "looking for ",$sfmail[$i]->{'id'}," found at ",$sfmail[$i]->{'idx'},"\n"; } } } @@ -506,7 +513,7 @@ if ($mail) { # No sorting, so sort index is the opposite of real $mail->{'sortidx'} = &mailbox_folder_size($folder, 1) - $mail->{'idx'} - 1; - print STDERR "idx=$mail->{'idx'} sortidx=$mail->{'sortidx'} size=",&mailbox_folder_size($folder, 1),"\n"; + print DEBUG "idx=$mail->{'idx'} sortidx=$mail->{'sortidx'} size=",&mailbox_folder_size($folder, 1),"\n"; } else { # Need to extract from sort index @@ -524,9 +531,9 @@ sub mailbox_idlist local ($folder) = @_; if ($folder->{'type'} == 0) { # mbox, for which IDs are mail positions - print STDERR "starting to get IDs from $folder->{'file'}\n"; + print DEBUG "starting to get IDs from $folder->{'file'}\n"; local @idlist = &idlist_mails($folder->{'file'}); - print STDERR "got ",scalar(@idlist)," ids\n"; + print DEBUG "got ",scalar(@idlist)," ids\n"; return @idlist; } elsif ($folder->{'type'} == 1) { @@ -657,18 +664,18 @@ if ($folder->{'type'} == 4 && !$folder->{'lastchange'}) { # Get a sorted list of IDs, and then find the real emails within the range local @sorter = &build_sorted_ids($folder, $field, $dir); ($start, $end) = &compute_start_end($start, $end, scalar(@sorter)); -print STDERR "for ",&folder_name($folder)," sorter = ",scalar(@sorter),"\n"; -print STDERR "start = $start end = $end\n"; +print DEBUG "for ",&folder_name($folder)," sorter = ",scalar(@sorter),"\n"; +print DEBUG "start = $start end = $end\n"; local @rv = map { undef } (0 .. scalar(@sorter)-1); local @wantids = map { $sorter[$_] } ($start .. $end); -print STDERR "wantids = ",scalar(@wantids),"\n"; +print DEBUG "wantids = ",scalar(@wantids),"\n"; local @mails = &mailbox_select_mails($folder, \@wantids, $headersonly); for(my $i=0; $i<@mails; $i++) { $rv[$start+$i] = $mails[$i]; - print STDERR "setting $start+$i to ",$mails[$i],"\n"; + print DEBUG "setting $start+$i to ",$mails[$i],"\n"; $mails[$i]->{'sortidx'} = $start+$i; } -print STDERR "rv = ",scalar(@rv),"\n"; +print DEBUG "rv = ",scalar(@rv),"\n"; return @rv; } @@ -782,7 +789,7 @@ return 0 if (!$folder->{'sortable'}); local $ifile = &folder_new_sort_index_file($folder); &open_dbm_db($index, $ifile, 0600); -print STDERR "indexchange=$index->{'lastchange'} folderchange=$folder->{'lastchange'}\n"; +print DEBUG "indexchange=$index->{'lastchange'} folderchange=$folder->{'lastchange'}\n"; if ($index->{'lastchange'} != $folder->{'lastchange'} || !$folder->{'lastchange'}) { # The mail file has changed .. get IDs and update the index with any @@ -790,6 +797,7 @@ if ($index->{'lastchange'} != $folder->{'lastchange'} || local @ids = &mailbox_idlist($folder); # Find IDs that are new + local @newids; foreach my $id (@ids) { if (!defined($index->{$id."_size"})) { push(@newids, $id); @@ -831,10 +839,10 @@ if ($index->{'lastchange'} != $folder->{'lastchange'} || } } } - print STDERR "added ",scalar(@mail)," messages to index\n"; + print DEBUG "added ",scalar(@mails)," messages to index\n"; # Remove IDs that no longer exist - local %ids = map { $_, 1 } @ids; + local %ids = map { $_, 1 } (@ids, @wantids); local $dc = 0; while(my ($k, $v) = each %$index) { if ($k =~ /^(.*)_([^_]+)$/ && !$ids{$1}) { @@ -842,12 +850,12 @@ if ($index->{'lastchange'} != $folder->{'lastchange'} || $dc++ if ($2 eq "size"); } } - print STDERR "deleted $dc mesages from index\n"; + print DEBUG "deleted $dc mesages from index\n"; # Record index update time $index->{'lastchange'} = $folder->{'lastchange'} || time(); $index->{'mailcount'} = scalar(@ids); - print STDERR "new indexchange=$index->{'lastchange'}\n"; + print DEBUG "new indexchange=$index->{'lastchange'}\n"; } return 1; } @@ -941,7 +949,7 @@ if ($folder->{'type'} != 4 && @matches = &unique(@matches); } @matches = sort { $a <=> $b } @matches; - print STDERR "matches = ",join(" ", @matches),"\n"; + print DEBUG "matches = ",join(" ", @matches),"\n"; # Select the actual mails return &mailbox_select_mails($_[2], \@matches, $headersonly); @@ -1036,10 +1044,10 @@ elsif ($folder->{'type'} == 5) { $limit = undef; foreach $sf (reverse(@{$folder->{'subfolders'}})) { local $sfn = &folder_name($sf); - print STDERR "searching on sub-folder ",&folder_name($sf),"\n"; + print DEBUG "searching on sub-folder ",&folder_name($sf),"\n"; local @submail = &mailbox_search_mail($fields, $andmode, $sf, $limit, $headersonly); - print STDERR "found ",scalar(@submail),"\n"; + print DEBUG "found ",scalar(@submail),"\n"; foreach my $sm (@submail) { $sm->{'id'} = $sfn."\t".$sm->{'id'}; } @@ -1062,7 +1070,7 @@ elsif ($folder->{'type'} == 6) { } local $mail; local $sfn = &folder_name($sf); - print STDERR "searching virtual folder ",&folder_name($folder),"\n"; + print DEBUG "searching virtual folder ",&folder_name($folder),"\n"; foreach $mail (&mailbox_list_mails($min, $max, $folder)) { if ($mail && &mail_matches($fields, $andmode, $mail)) { push(@rv, $mail); @@ -1608,7 +1616,7 @@ local ($h, $c) = @_; print $h "$c\r\n" if ($c); local $rv = <$h>; $rv =~ s/\r|\n//g; -print STDERR "pop3 $c -> $rv\n"; +print DEBUG "pop3 $c -> $rv\n"; return !$rv ? ( 0, "Connection closed" ) : $rv =~ /^\+OK\s*(.*)/ ? ( 1, $1 ) : $rv =~ /^\-ERR\s*(.*)/ ? ( 0, $1 ) : ( 0, $rv ); @@ -1720,7 +1728,7 @@ local @rv; local $id = $$."-".$imap_command_count++; if ($c) { print $h "$id $c\r\n"; - print STDERR "imap command $id $c\n"; + print DEBUG "imap command $id $c\n"; } while(1) { local $l = <$h>; @@ -2042,21 +2050,20 @@ else { } } -# folder_select(&folders, selected-folder, name, [extra-options], [by-id]) +# folder_select(&folders, selected-folder, name, [extra-options], [by-id], +# [auto-submit]) # Returns HTML for selecting a folder sub folder_select { -local $sel = "\n"; +return &ui_select($name, $byid ? &folder_name($folder) : $folder->{'index'}, + \@opts, 1, 0, 0, 0, $auto ? "onChange='form.submit()'" : ""); return $sel; } diff --git a/mailboxes/lang/en b/mailboxes/lang/en index 4b349596e..568cf143a 100644 --- a/mailboxes/lang/en +++ b/mailboxes/lang/en @@ -125,6 +125,9 @@ view_mark=Mark as: view_mark0=Unread view_mark1=Read view_mark2=Special +view_markas0=Mark unread +view_markas1=Mark read +view_markas2=Mark special view_return=original email view_sub=Attached Email view_egone=This message no longer exists @@ -234,12 +237,14 @@ delete_errc=Failed to copy mail delete_errm=Failed to move mail confirm_title=Confirm Delete -confirm_warn=Are you sure you want to delete the $1 selected messages? +confirm_warn=Are you sure you want to delete the $1 selected messages from this folder? +confirm_warnf=Are you sure you want to delete the $1 selected messages from the folder $2? confirm_warn2=Because of the size and format of your mailbox, this may take some time. Until the deletion has finished, no other action should be performed. confirm_warn3=Are you sure you want to delete this message? confirm_warn4=Until the deletion has finished, no other action should be performed. confirm_ok=Delete Now confirm_warnall=Are you sure you want to delete all of the messages in this folder? +confirm_warnallf=Are you sure you want to delete all of the messages in the folder $1? search_title=Search Results search_ecannot=You are not allowed to search this user's email @@ -281,12 +286,14 @@ detach_title=Detach File detach_ok=Wrote attachment to server-side file $1 ($2). sform_title=Advanced Search +sform_header=Advanced email search options +sform_andmode=Criteria mode sform_and=Find messages matching all criteria below .. sform_or=Find messages matches any criteria below .. sform_neg0=contains sform_neg1=doesn't contain sform_ok=Search Now -sform_folder=in folder(s) +sform_folder2=Search in folder(s) sform_all=<All folders> sform_local=<Local folders> sform_where=Where @@ -299,7 +306,7 @@ sform_bcc=Bcc: header sform_date=Date: header sform_body=message body sform_headers=any header -sform_all=entire message +sform_allmsg=entire message sform_size=message size sform_return=advanced search form