* SusiMail:

- Show sender name in folder view
   - Add support for configured sender name
   - Add HTML escaping of '&'
   - Fix Folder sorting so UP is up and DOWN is down
   - Use replace() instead of replaceAll() where appropriate
   - Fix capture by show page after back button
This commit is contained in:
zzz
2014-04-22 18:45:09 +00:00
parent 6986f90bf8
commit 4d2dc1c8e8
6 changed files with 119 additions and 57 deletions

View File

@@ -51,13 +51,17 @@ public class Folder<O extends Object> {
public static final String PAGESIZE = "pager.pagesize";
public static final int DEFAULT_PAGESIZE = 10;
public static final boolean DOWN = false;
public static final boolean UP = true;
public enum SortOrder {
/** lowest to highest */
DOWN,
/** reverse sort, highest to lowest */
UP;
}
private int pages, pageSize, currentPage;
private O[] unsortedElements, elements;
private final Hashtable<String, Comparator<O>> sorter;
private boolean sortingDirection;
private SortOrder sortingDirection;
Comparator<O> currentSorter;
public Folder()
@@ -65,7 +69,7 @@ public class Folder<O extends Object> {
pages = 1;
currentPage = 1;
sorter = new Hashtable<String, Comparator<O>>();
sortingDirection = UP;
sortingDirection = SortOrder.DOWN;
}
/**
@@ -232,14 +236,9 @@ public class Folder<O extends Object> {
if( elements != null ) {
int pageSize = getPageSize();
int offset = ( currentPage - 1 ) * pageSize;
int step = 1;
if( sortingDirection == DOWN ) {
offset = elements.length - offset - 1;
step = -1;
}
for( int i = 0; i < pageSize && offset >= 0 && offset < elements.length; i++ ) {
list.add( elements[offset] );
offset += step;
offset++;
}
}
return list.iterator();
@@ -303,6 +302,8 @@ public class Folder<O extends Object> {
public void sortBy( String id )
{
currentSorter = sorter.get( id );
if (sortingDirection == SortOrder.UP)
currentSorter = Collections.reverseOrder(currentSorter);
sort();
}
@@ -318,12 +319,7 @@ public class Folder<O extends Object> {
if( elements != null ) {
int pageSize = getPageSize();
int offset = ( currentPage - 1 ) * pageSize;
int step = 1;
if( sortingDirection == DOWN ) {
offset = elements.length - offset - 1;
step = -1;
}
offset += x * step;
offset += x;
if( offset >= 0 && offset < elements.length )
result = elements[offset];
}
@@ -332,10 +328,11 @@ public class Folder<O extends Object> {
/**
* Sets the sorting direction of the folder.
* Does not re-sort. Caller must call sortBy()
*
* @param direction @link UP or @link DOWN
*/
public void setSortingDirection( boolean direction )
public void setSortingDirection(SortOrder direction)
{
sortingDirection = direction;
}
@@ -347,9 +344,6 @@ public class Folder<O extends Object> {
*/
public O getFirstElement()
{
/*
* sorting direction is taken into account from getElement
*/
return elements == null ? null : getElement( 0 );
}
@@ -360,9 +354,6 @@ public class Folder<O extends Object> {
*/
public O getLastElement()
{
/*
* sorting direction is taken into account from getElement
*/
return elements == null ? null : getElement( elements.length - 1 );
}
@@ -384,7 +375,6 @@ public class Folder<O extends Object> {
/**
* Retrieves the next element in the sorted array.
* Sorting direction is taken into account.
*
* @param element
* @return The next element
@@ -396,7 +386,7 @@ public class Folder<O extends Object> {
int i = getIndexOf( element );
if( i != -1 && elements != null ) {
i += sortingDirection == UP ? 1 : -1;
i++;
if( i >= 0 && i < elements.length )
result = elements[i];
}
@@ -405,7 +395,6 @@ public class Folder<O extends Object> {
/**
* Retrieves the previous element in the sorted array.
* Sorting direction is taken into account.
*
* @param element
* @return The previous element
@@ -417,14 +406,14 @@ public class Folder<O extends Object> {
int i = getIndexOf( element );
if( i != -1 && elements != null ) {
i += sortingDirection == DOWN ? 1 : -1;
i--;
if( i >= 0 && i < elements.length )
result = elements[i];
}
return result;
}
/**
* Retrieves element at index i. Depends on sorting direction.
* Retrieves element at index i.
*
* @param i
* @return Element at index i
@@ -434,8 +423,6 @@ public class Folder<O extends Object> {
O result = null;
if( elements != null ) {
if( sortingDirection == DOWN )
i = elements.length - i - 1;
result = elements[i];
}
return result;
@@ -459,7 +446,6 @@ public class Folder<O extends Object> {
/**
* Returns true, if elements.equals( lastElementOfTheSortedArray ).
* The sorting direction influences which element is taken for comparison.
*
* @param element
*/
@@ -467,12 +453,11 @@ public class Folder<O extends Object> {
{
if( elements == null )
return false;
return elements[ sortingDirection == DOWN ? 0 : elements.length - 1 ].equals( element );
return elements[elements.length - 1].equals( element );
}
/**
* Returns true, if elements.equals( firstElementOfTheSortedArray ).
* The sorting direction influences which element is taken for comparison.
*
* @param element
*/
@@ -480,6 +465,6 @@ public class Folder<O extends Object> {
{
if( elements == null )
return false;
return elements[ sortingDirection == UP ? 0 : elements.length - 1 ].equals( element );
return elements[0].equals( element );
}
}

View File

@@ -55,17 +55,20 @@ class Mail {
private static final String unknown = "unknown";
private int size;
public String sender, reply, subject, dateString,
formattedSender, formattedSubject,
public String sender, // as received, trimmed only, not HTML escaped
reply, subject, dateString,
formattedSender, // address only, enclosed with <>, not HTML escaped
formattedSubject,
formattedDate, // US Locale, UTC
localFormattedDate, // Current Locale, local time zone
shortSender, shortSubject,
shortSender, // Either name or address but not both, HTML escaped, double-quotes removed, truncated with with hellip
shortSubject, // HTML escaped, truncated with hellip
quotedDate; // Current Locale, local time zone, longer format
public final String uidl;
public Date date;
private ReadBuffer header, body;
private MailPart part;
String[] to, cc;
String[] to, cc; // addresses only, enclosed by <>
public String error;
@@ -165,7 +168,9 @@ class Mail {
}
return addresses == 1;
}
/**
* Returns the first email address portion, enclosed by <>
* @param address
*/
public static String getAddress(String address )
@@ -181,6 +186,16 @@ class Mail {
return null;
}
/**
* A little misnamed. Adds all addresses from the comma-separated
* line in text to the recipients list.
*
* @param text comma-separated
* @param recipients out param
* @param ok will be returned
* @return true if ALL e-mail addresses are valid AND the in parameter was true
*/
public static boolean getRecipientsFromList( ArrayList<String> recipients, String text, boolean ok )
{
if( text != null && text.length() > 0 ) {
@@ -203,6 +218,15 @@ class Mail {
}
return ok;
}
/**
* Adds all items from the list
* to the builder, separated by tabs.
*
* @param text comma-separated
* @param buf out param
* @param prefix prepended to the addresses
*/
public static void appendRecipients( StringBuilder buf, ArrayList<String> recipients, String prefix )
{
for( String recipient : recipients ) {
@@ -212,6 +236,7 @@ class Mail {
buf.append( "\r\n" );
}
}
public void parseHeaders()
{
DateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
@@ -258,11 +283,18 @@ class Mail {
if( line.startsWith( "From:" ) ) {
sender = line.substring( 5 ).trim();
formattedSender = getAddress( sender );
shortSender = formattedSender.trim();
if( shortSender.length() > 40 ) {
shortSender = shortSender.substring( 0, 37 ).trim() + "&hellip;";
}
shortSender = sender.replace("\"", "").trim();
int lt = shortSender.indexOf('<');
if (lt > 0)
shortSender = shortSender.substring(0, lt).trim();
else if (lt < 0 && shortSender.contains("@"))
shortSender = '<' + shortSender + '>'; // add missing <> (but thunderbird doesn't...)
boolean trim = shortSender.length() > 40;
if (trim)
shortSender = shortSender.substring( 0, 37 ).trim();
shortSender = html.encode( shortSender );
if (trim)
shortSender += "&hellip;"; // must be after html encode
}
else if( line.startsWith( "Date:" ) ) {
dateString = line.substring( 5 ).trim();
@@ -282,9 +314,12 @@ class Mail {
subject = line.substring( 8 ).trim();
formattedSubject = subject;
shortSubject = formattedSubject;
if( formattedSubject.length() > 60 )
shortSubject = formattedSubject.substring( 0, 57 ).trim() + "&hellip;";
boolean trim = formattedSubject.length() > 60;
if (trim)
shortSubject = formattedSubject.substring( 0, 57 ).trim();
shortSubject = html.encode( shortSubject );
if (trim)
shortSubject += "&hellip;"; // must be after html encode
}
else if( line.toLowerCase(Locale.US).startsWith( "reply-to:" ) ) {
reply = getAddress( line.substring( 9 ).trim() );

View File

@@ -167,6 +167,7 @@ public class WebMail extends HttpServlet
private static final String CONFIG_SENDER_FIXED = "sender.fixed";
private static final String CONFIG_SENDER_DOMAIN = "sender.domain";
private static final String CONFIG_SENDER_NAME = "sender.name";
private static final String CONFIG_COMPOSER_COLS = "composer.cols";
private static final String CONFIG_COMPOSER_ROWS = "composer.rows";
@@ -244,7 +245,9 @@ public class WebMail extends HttpServlet
return (b == null) ? 0 : 1;
if (b == null)
return -1;
return collator.compare(a.formattedSender, b.formattedSender);
String as = a.sender.replace("\"", "").replace("<", "").replace(">", "");
String bs = b.sender.replace("\"", "").replace("<", "").replace(">", "");
return collator.compare(as, bs);
}
}
@@ -578,7 +581,7 @@ public class WebMail extends HttpServlet
static String quoteHTML( String line )
{
if( line != null )
line = line.replaceAll( "<", "&lt;" ).replaceAll( ">", "&gt;" );
line = line.replace("&", "&amp;").replace( "<", "&lt;" ).replace( ">", "&gt;" );
else
line = "";
return line;
@@ -689,7 +692,8 @@ public class WebMail extends HttpServlet
sessionObject.folder.addSorter( SORT_SUBJECT, new SubjectSorter( sessionObject.mailCache ) );
sessionObject.folder.addSorter( SORT_DATE, new DateSorter( sessionObject.mailCache ) );
sessionObject.folder.addSorter( SORT_SIZE, new SizeSorter( sessionObject.mailCache ) );
sessionObject.folder.setSortingDirection( Folder.DOWN );
// reverse sort, latest mail first
sessionObject.folder.setSortingDirection(Folder.SortOrder.UP);
sessionObject.folder.sortBy(SORT_DATE);
sessionObject.reallyDelete = false;
Debug.debug(Debug.DEBUG, "CONNECTED, YAY");
@@ -816,6 +820,22 @@ public class WebMail extends HttpServlet
if( sessionObject.state == STATE_SHOW ) {
if( buttonPressed( request, LIST ) ) {
sessionObject.state = STATE_LIST;
} else if (buttonPressed( request, CANCEL ) ||
buttonPressed( request, PREVPAGE ) || // All these buttons are not shown but we could be lost
buttonPressed( request, NEXTPAGE ) ||
buttonPressed( request, FIRSTPAGE ) ||
buttonPressed( request, LASTPAGE ) ||
buttonPressed( request, SETPAGESIZE ) ||
buttonPressed( request, MARKALL ) ||
buttonPressed( request, CLEAR ) ||
buttonPressed( request, INVERT ) ||
buttonPressed( request, SORT_ID ) ||
buttonPressed( request, SORT_SENDER ) ||
buttonPressed( request, SORT_SUBJECT ) ||
buttonPressed( request, SORT_DATE ) ||
buttonPressed( request, SORT_SIZE ) ||
buttonPressed( request, REFRESH )) {
sessionObject.state = STATE_LIST;
}
}
/*
@@ -865,9 +885,9 @@ public class WebMail extends HttpServlet
if (part != null) {
if( reply || replyAll ) {
if( mail.reply != null && Mail.validateAddress( mail.reply ) )
sessionObject.replyTo = Mail.getAddress( mail.reply );
sessionObject.replyTo = mail.reply;
else if( mail.sender != null && Mail.validateAddress( mail.sender ) )
sessionObject.replyTo = Mail.getAddress( mail.sender );
sessionObject.replyTo = mail.sender;
sessionObject.subject = "Re: " + mail.formattedSubject;
StringWriter text = new StringWriter();
PrintWriter pw = new PrintWriter( text );
@@ -1274,11 +1294,10 @@ public class WebMail extends HttpServlet
String str = request.getParameter( sort_id );
if( str != null ) {
if( str.equalsIgnoreCase("up")) {
sessionObject.folder.setSortingDirection( Folder.UP );
sessionObject.folder.setSortingDirection(Folder.SortOrder.UP);
sessionObject.folder.sortBy( sort_id );
}
if( str.equalsIgnoreCase("down")) {
sessionObject.folder.setSortingDirection( Folder.DOWN );
} else if( str.equalsIgnoreCase("down")) {
sessionObject.folder.setSortingDirection(Folder.SortOrder.DOWN);
sessionObject.folder.sortBy( sort_id );
}
}
@@ -1550,7 +1569,7 @@ public class WebMail extends HttpServlet
name = part.name;
else
name = "part" + part.hashCode();
String name2 = name.replaceAll( "\\.", "_" );
String name2 = name.replace( "\\.", "_" );
response.setContentType( "application/zip; name=\"" + name2 + ".zip\"" );
response.addHeader( "Content-Disposition:", "attachment; filename=\"" + name2 + ".zip\"" );
ZipEntry entry = new ZipEntry( name );
@@ -1740,8 +1759,23 @@ public class WebMail extends HttpServlet
String fixed = Config.getProperty( CONFIG_SENDER_FIXED, "true" );
if( from == null || !fixed.equalsIgnoreCase("false")) {
String user = sessionObject.user;
String name = Config.getProperty(CONFIG_SENDER_NAME);
if (name != null) {
name = name.trim();
if (name.contains(" "))
from = '"' + name + "\" ";
else
from = name + ' ';
} else {
from = "";
}
if (user.contains("@")) {
String domain = Config.getProperty( CONFIG_SENDER_DOMAIN, "mail.i2p" );
from = "<" + sessionObject.user + "@" + domain + ">";
from += '<' + user + '@' + domain + '>';
} else {
from += '<' + user + '>';
}
}
String to = request.getParameter( NEW_TO, sessionObject.replyTo != null ? sessionObject.replyTo : "" );

View File

@@ -50,7 +50,10 @@ public class HTML implements Encoding {
*/
public String encode(String str) throws EncodingException
{
return str.replaceAll( "<", "&lt;" ).replaceAll( ">", "&gt;" ).replaceAll( "\r{0,1}\n", "<br>\r\n" );
return str.replace("&", "&amp;") // must be first
.replace( "<", "&lt;" )
.replace( ">", "&gt;" )
.replaceAll( "\r{0,1}\n", "<br>\r\n" );
}
/* (non-Javadoc)

View File

@@ -263,7 +263,7 @@ public class SMTPClient {
}
if (ok) {
if( body.indexOf( "\r\n.\r\n" ) != -1 )
body = body.replaceAll( "\r\n.\r\n", "\r\n..\r\n" );
body = body.replace( "\r\n.\r\n", "\r\n..\r\n" );
socket.getOutputStream().write(DataHelper.getUTF8(body));
socket.getOutputStream().write(DataHelper.getASCII("\r\n.\r\n"));
int result = sendCmd(null);

View File

@@ -2,6 +2,11 @@
* SusiMail:
- Add persistent cache
- Fix encoding in sent mails on non-UTF8 platforms
- Show sender name in folder view
- Add support for configured sender name
- Add HTML escaping of '&'
- Fix Folder sorting so UP is up and DOWN is down
- Fix capture by show page after back button
2014-04-21 zzz
* SusiMail: