/**
* Copyright (c) 2005-2017, KoLmafia development team
* http://kolmafia.sourceforge.net/
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* [1] Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* [2] Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
* [3] Neither the name "KoLmafia" nor the names of its contributors may
* be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
* ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package net.sourceforge.kolmafia.request;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import net.sourceforge.kolmafia.BuffBotHome;
import net.sourceforge.kolmafia.KoLMailMessage;
import net.sourceforge.kolmafia.KoLmafia;
import net.sourceforge.kolmafia.StaticEntity;
import net.sourceforge.kolmafia.session.BuffBotManager;
import net.sourceforge.kolmafia.session.MailManager;
import net.sourceforge.kolmafia.utilities.StringUtilities;
public class MailboxRequest
extends GenericRequest
{
private static final Pattern MULTIPAGE_PATTERN =
Pattern.compile( "Messages: \\w*?, page \\d* \\(\\d* - (\\d*) of (\\d*)\\)</b>" );
private static final Pattern SINGLEPAGE_PATTERN =
Pattern.compile( "Messages: \\w*?, page 1 \\((\\d*) messages\\)</b>" );
private int beginIndex;
private final String boxname;
private final String action;
public MailboxRequest( final String boxname, final KoLMailMessage message, final String action )
{
this( boxname, new Object[] { message }, action );
}
public MailboxRequest( final String boxname, final Object[] messages, final String action )
{
super( "messages.php" );
this.addFormField( "box", boxname );
this.addFormField( "the_action", action );
this.action = action;
this.boxname = boxname;
this.beginIndex = 1 ;
for ( int i = 0; i < messages.length; ++i )
{
this.addFormField( ( (KoLMailMessage) messages[ i ] ).getMessageId(), "on" );
}
}
public MailboxRequest( final String boxname )
{
this( boxname, 1 );
}
public MailboxRequest( final String boxname, final int beginIndex )
{
super( "messages.php" );
this.addFormField( "box", boxname );
if ( beginIndex != 1 )
{
this.addFormField( "begin", String.valueOf( beginIndex ) );
}
this.action = null;
this.boxname = boxname;
this.beginIndex = beginIndex;
}
@Override
protected boolean retryOnTimeout()
{
return true;
}
@Override
public void run()
{
// Now you know that there is a request in progress, so you
// reset the variable (to avoid concurrent requests).
if ( this.action == null )
{
KoLmafia.updateDisplay( "Retrieving mail from " + this.boxname + "..." );
}
else
{
KoLmafia.updateDisplay( "Executing " + this.action + " request for " + this.boxname + "..." );
}
super.run();
}
@Override
public void processResults()
{
// Determine how many messages there are, and how many there
// are left to go. This will cause a lot of server load for
// those with lots of messages. But! This can be fixed by
// testing the mail manager to see if it thinks all the new
// messages have been retrieved.
if ( this.responseText.indexOf( "There are no messages in this mailbox." ) != -1 )
{
KoLmafia.updateDisplay( "Your mailbox is empty." );
return;
}
int lastMessageId = 0;
int totalMessages = Integer.MAX_VALUE;
try
{
Matcher matcher = MailboxRequest.MULTIPAGE_PATTERN.matcher( this.responseText );
if ( matcher.find() )
{
lastMessageId = StringUtilities.parseInt( matcher.group( 1 ) );
totalMessages = StringUtilities.parseInt( matcher.group( 2 ) );
}
else
{
matcher = MailboxRequest.SINGLEPAGE_PATTERN.matcher( this.responseText );
if ( matcher.find() )
{
lastMessageId = StringUtilities.parseInt( matcher.group( 1 ) );
totalMessages = lastMessageId;
}
}
}
catch ( Exception e )
{
// This should not happen. Therefore, print
// a stack trace for debug purposes.
StaticEntity.printStackTrace( e, "Error in mail retrieval" );
return;
}
if ( this.responseText.indexOf( "<td valign=top>" ) == -1 )
{
KoLmafia.updateDisplay( "Your mailbox is empty." );
return;
}
this.processMessages();
KoLmafia.updateDisplay( "Mail retrieved from page " + this.beginIndex + " of " + this.boxname );
if ( this.boxname.equals( "PvP" ) && lastMessageId != totalMessages )
{
( new MailboxRequest( "PvP", this.beginIndex + 1 ) ).run();
}
}
private void processMessages()
{
boolean shouldContinueParsing = true;
int lastMessageIndex = 0;
int nextMessageIndex = this.responseText.indexOf( "<td valign=top>" );
String currentMessage;
do
{
lastMessageIndex = nextMessageIndex;
nextMessageIndex = this.responseText.indexOf( "<td valign=top>", lastMessageIndex + 15 );
// The last message in the inbox has no "next message
// index". In this case, locate the bold X and use
// that as the next message index.
if ( nextMessageIndex == -1 )
{
nextMessageIndex = this.responseText.indexOf( "<b>X</b>", lastMessageIndex + 15 );
shouldContinueParsing = false;
}
if ( nextMessageIndex == -1 )
{
return;
}
// If the next message index is still non-positive, that
// means there aren't any messages left to parse.
currentMessage = this.responseText.substring( lastMessageIndex, nextMessageIndex );
// This replaces all of the HTML contained within the message to something
// that can be rendered with the default RequestPane, and also be subject
// to the custom font sizes provided by LimitedSizeChatBuffer.
currentMessage =
currentMessage.replaceAll( "<br />", "<br>" ).replaceAll( "</?t.*?>", "\n" ).replaceAll(
"<blockquote>", "<br>" ).replaceAll( "</blockquote>", "" ).replaceAll( "\n", "" ).replaceAll(
"<center>", "<br><center>" );
// At this point, the message is registered with the mail manager, which
// records the message and updates whether or not you should continue.
if ( BuffBotHome.isBuffBotActive() )
{
shouldContinueParsing = BuffBotManager.addMessage( this.boxname, currentMessage ) != null;
}
else
{
shouldContinueParsing = MailManager.addMessage( this.boxname, currentMessage ) != null;
}
}
while ( shouldContinueParsing && nextMessageIndex != -1 );
}
}