package com.bao.lc.site.s3.commands;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.chain.Context;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpUriRequest;
import com.bao.lc.ResMgr;
import com.bao.lc.bean.IDValuePair;
import com.bao.lc.bean.ResultCode;
import com.bao.lc.client.RequestBuilder;
import com.bao.lc.client.utils.HttpClientUtils;
import com.bao.lc.common.URI2NameBuilder;
import com.bao.lc.httpcommand.BasicHttpCommand;
import com.bao.lc.httpcommand.params.HttpCommandPNames;
import com.bao.lc.httpcommand.params.HttpCommandParams;
import com.bao.lc.site.s3.TdUtils;
import com.bao.lc.site.s3.ai.TrainTicketSelector;
import com.bao.lc.site.s3.bean.TrainTicketInfo;
import com.bao.lc.site.s3.params.TdPNames;
import com.bao.lc.site.s3.params.TdParams;
import com.bao.lc.util.MiscUtils;
public class QueryLeftTicket extends BasicHttpCommand
{
private static Log log = LogFactory.getLog(QueryLeftTicket.class);
public QueryLeftTicket()
{
super();
}
protected IDValuePair preExecute(Context context) throws Exception
{
// Remove the response if it exists
HttpCommandParams.purgeResponseParams(context);
//Request
context.put(HttpCommandPNames.TARGET_REQUEST, buildTargetRequest(context));
//Referrer
String referer = MapUtils.getString(context, TdPNames.PARAM_QUERY_LEFT_TICKET_REFERER);
context.put(HttpCommandPNames.TARGET_REFERER, referer);
return ResultCode.RC_OK;
}
protected IDValuePair postExecute(Context context) throws Exception
{
//1. Save the response content
HttpResponse rsp = HttpCommandParams.getResponse(context);
String charset = HttpCommandParams.getCharset(rsp, context);
URI2NameBuilder ub = new URI2NameBuilder();
ub.uri(HttpCommandParams.getTargetRequestURI(context));
ub.addParamName("method").encoding(charset);
String content = HttpClientUtils.saveToString(rsp.getEntity(), charset, ub);
//2. Parse
IDValuePair rc = parseResponseContent(context, content);
return rc;
}
private HttpUriRequest buildTargetRequest(Context context)
{
RequestBuilder rb = new RequestBuilder();
String uriString = MapUtils.getString(context, TdPNames.PARAM_QUERY_LEFT_TICKET_BASE_URL);
String encoding = HttpCommandParams.getDefaultResponseCharset(context);
rb.method(HttpGet.METHOD_NAME).uriStr(uriString).encoding(encoding);
rb.paramMap(getParamMap(context));
return rb.create();
}
private Map<String, String> getParamMap(Context context)
{
//Refer from: function loadData() @ https://dynamic.12306.cn/otsweb/js/order/query_single_bindevent.js?version=2.4
/**
* $.ajax( {
url : ctx+'/order/querySingleAction.do?method=queryLeftTicket',
type : "GET",
dataType:'text',
data:{
'orderRequest.train_date' : $('#startdatepicker').val(),
'orderRequest.from_station_telecode' : $('#fromStation').val(),
'orderRequest.to_station_telecode' : $('#toStation').val(),
'orderRequest.train_no' : $('#trainCode').val(),
'trainPassType' : getTrainPassType(),
'trainClass' : getTrainClassString(),
'includeStudent' : getIncludeStudent(),
'seatTypeAndNum' : getSeanTypeAndNum(),
'orderRequest.start_time_str' : $('#startTime').val()
},
*/
String fromStation = MapUtils.getString(context, TdPNames.PARAM_FROM_STATION);
String toStation = MapUtils.getString(context, TdPNames.PARAM_TO_STATION);
String ticketDate = MapUtils.getString(context, TdPNames.PARAM_TICKET_DATE);
String ticketTimeRange = MapUtils.getString(context, TdPNames.PARAM_TICKET_TIME_RANGE);
Map<String, String> paramMap = new HashMap<String, String>();
paramMap.put("orderRequest.train_date", ticketDate);
paramMap.put("orderRequest.from_station_telecode", TdUtils.getStationCode(fromStation));
paramMap.put("orderRequest.to_station_telecode", TdUtils.getStationCode(toStation));
paramMap.put("orderRequest.train_no", "");
paramMap.put("trainPassType", "QB");
paramMap.put("trainClass", "QB#D#Z#T#K#QT#");
paramMap.put("includeStudent", "00");
paramMap.put("seatTypeAndNum", "");
paramMap.put("orderRequest.start_time_str", ticketTimeRange);
if(log.isDebugEnabled())
{
log.debug("paramMap=" + MiscUtils.toString(paramMap));
}
return paramMap;
}
private IDValuePair parseResponseContent(Context context, String content)
{
if(log.isTraceEnabled())
{
log.trace("raw data: " + content);
}
String str = content.replaceAll(" ", "");
String[] rows = str.split("\\\\n");
List<TrainTicketInfo> ticketInfoList = new ArrayList<TrainTicketInfo>(rows.length);
for(String row : rows)
{
String[] fields = row.split(",");
if(fields.length < TrainTicketInfo.RAW_FIELD_COUNT)
{
log.error("The ticket info is incomplete. row=" + row + ", raw data: " + content);
return ResultCode.RC_TD_QUERY_LEFT_TICKET_ERROR;
}
TrainTicketInfo ticketInfo = new TrainTicketInfo(fields, 0);
ticketInfoList.add(ticketInfo);
}
context.put(TdPNames._TICKET_INFO_LIST, ticketInfoList);
if(log.isDebugEnabled())
{
log.debug("ticketInfoList=" + ticketInfoList);
}
StringBuilder sb = new StringBuilder();
for(TrainTicketInfo ticket : ticketInfoList)
{
sb.append("\n").append(ticket.toString());
}
String message = null;
message = MessageFormat.format(ResMgr.getString("td.msg.ticket.found.count"),
String.valueOf(ticketInfoList.size()), sb.toString());
TdParams.getUI(context).info(message);
TrainTicketSelector selector = new TrainTicketSelector(ticketInfoList, context);
TrainTicketInfo ticket = selector.select();
if(ticket == null)
{
TdParams.getUI(context).info(ResMgr.getString("td.msg.ticket.filter.all"));
return ResultCode.RC_TD_NO_AVAILABLE_TICKET_WITH_FILTER;
}
context.put(TdPNames._ORDER_TICKET_INFO, ticket);
message = MessageFormat.format(ResMgr.getString("td.msg.ticket.filter.best.match"),
ticket.toString());
TdParams.getUI(context).info(message);
return ResultCode.RC_OK;
}
}