package com.bao.lc.site.sx;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import net.sf.json.JSONObject;
import net.sf.json.JSONSerializer;
import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.URIUtils;
import org.apache.http.cookie.Cookie;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;
import com.bao.lc.AppConfig;
import com.bao.lc.client.BrowserClient;
import com.bao.lc.client.RequestBuilder;
import com.bao.lc.client.utils.HttpClientUtils;
import com.bao.lc.common.exception.ParseException;
import com.bao.lc.util.AppUtils;
import com.bao.lc.util.MiscUtils;
public class CnetUser
{
private static Log log = LogFactory.getLog(CnetUser.class);
private BrowserClient session = null;
private boolean isLogin = false;
private String user = null;
private String password = null;
private String profileContent = null;
private HttpHost host = null;
public CnetUser(String user, String password)
{
session = new BrowserClient();
HttpProtocolParams.setUserAgent(session.getParams(), BrowserClient.AGENT_CHROME);
isLogin = false;
this.user = user;
this.password = password;
profileContent = null;
getDefaultHost();
}
private void getDefaultHost()
{
String url = AppConfig.getInstance().getPropInternal("cnet.url.main");
try
{
URI uri = new URI(url);
host = URIUtils.extractHost(uri);
}
catch(URISyntaxException e)
{
log.error(String.format("Failed to convert url=[%s] to URI", url), e);
}
}
public int get()
{
int rc = 0;
try
{
do
{
if(!login())
{
rc = -1;
break;
}
getComminityProfile();
modifyProfile("Colin", "Conger", "MALE", "09/17/1983");
}
while(false);
}
catch(Exception e)
{
log.error(e.toString(), e);
}
finally
{
if(isLogin)
{
try
{
logout();
}
catch(Exception e2)
{
log.error(e2.toString(), e2);
}
}
session.getConnectionManager().shutdown();
}
return rc;
}
public boolean login() throws ClientProtocolException, IOException,
ParseException
{
isLogin = false;
HttpResponse rsp = null;
String url = null;
String content = null;
// 1. main page for referer
url = AppConfig.getInstance().getPropInternal("cnet.url.main");
rsp = session.execute(url);
// 2. login page
url = AppConfig.getInstance().getPropInternal("cnet.url.login");
Map<String, String> params = new HashMap<String, String>();
params.put("appId", "223");
params.put("email", user);
params.put("password", password);
params.put("rememberMe", "true");
params.put("resource", "rps-authenticate");
params.put("viewType", "json");
RequestBuilder rb = new RequestBuilder();
rb.method(HttpPost.METHOD_NAME).uriStr(url).paramMap(params).encoding("UTF-8");
rsp = session.execute(rb);
// parse result
content = EntityUtils.toString(rsp.getEntity(), "UTF-8");
Map<String, String> resultMap = new HashMap<String, String>();
String errorMessage = parseLoginResult(content, resultMap);
if(errorMessage != null)
{
log.info(String.format("User [%s] login failed: %s.", user, errorMessage));
return false;
}
updateCookie(resultMap);
//3. try to get user profile page to check if we are really successfully login
url = AppConfig.getInstance().getPropInternal("cnet.url.main_profile");
params.clear();
params.put("tag", "hdr;brandnav");
rsp = session.execute(url);
HttpClientUtils.saveToFile(rsp.getEntity(), AppUtils.getTempFilePath("profile.html"));
profileContent = IOUtils.toString(
new FileInputStream(AppUtils.getTempFilePath("profile.html")), "UTF-8");
String userName = getLoginUserName();
isLogin = (userName != null);
if(!isLogin)
{
log.info(String.format("User [%s] login failed.", user));
return false;
}
log.info(String.format("User [%s] login succeeded. userName=[%s].", user, userName));
return isLogin;
}
public boolean logout() throws ClientProtocolException, IOException, ParseException, URISyntaxException
{
String logoutPageRegex = "<a class=\"logOut\" href=\"(.+?)\">Log out</a>";
String logoutPage = MiscUtils.getRegexValueOnce(profileContent, logoutPageRegex, 1);
URI logoutURI = URIUtils.rewriteURI(URI.create(logoutPage), host);
HttpResponse rsp = session.execute(logoutURI.toString());
HttpClientUtils.saveToFile(rsp.getEntity(), AppUtils.getTempFilePath("logout.html"));
boolean result = (rsp.getStatusLine().getStatusCode() == 200);
if(result)
{
isLogin = false;
}
log.info(String.format("User [%s] logout %s.", user, (result ? "succeeded" : "failed")));
return result;
}
public boolean getComminityProfile() throws ClientProtocolException, IOException, ParseException, URISyntaxException
{
String regex = "<a class=\"itemName\" href=\"(.+?)\">Community Profile</a>";
String url = MiscUtils.getRegexValueOnce(profileContent, regex, 1);
Map<String, String> params = new HashMap<String, String>(1);
params.put("tag", "contentMain;contentBody");
URI uri = URIUtils.rewriteURI(URI.create(url), host);
RequestBuilder rb = new RequestBuilder();
rb.uri(uri).paramMap(params);
HttpResponse rsp = session.execute(rb);
HttpClientUtils.saveToFile(rsp.getEntity(), AppUtils.getTempFilePath("community-profile.html"));
return (rsp.getStatusLine().getStatusCode() == 200);
}
public boolean modifyProfile(String firstName, String lastName, String gender, String birthday)
throws ClientProtocolException, IOException, ParseException
{
URI uri = URI.create(AppConfig.getInstance().getPropInternal("cnet.url.main_profile"));
//1. First get update url
String regex = "<ul class=\"settings\"> <li><a href=\"(.+?)\">Update my e-mail address</a></li> <li>";
String url = MiscUtils.getRegexValueOnce(profileContent, regex, 1);
uri = uri.resolve(url);
HttpResponse rsp = session.execute(new RequestBuilder().uri(uri));
HttpClientUtils.saveToFile(rsp.getEntity(), AppUtils.getTempFilePath("modifyProfile.html"));
String content = IOUtils.toString(
new FileInputStream(AppUtils.getTempFilePath("modifyProfile.html")), "UTF-8");
regex = "<input type=\"hidden\" name=\"path\" value=\"(.+?)\"(.*?)/>";
String path = MiscUtils.getRegexValueOnce(content, regex, 1);
regex = "<form onSubmit=\"(.+?)\" name=\"mainForm\" method=\"POST\" action=\"(.+?)\">";
url = MiscUtils.getRegexValueOnce(content, regex, 2);
uri = uri.resolve(url);
//2. Post modify request
Map<String, String> params = new HashMap<String, String>();
params.put("COUNTRY", "US");
params.put("DATEOFBIRTH", birthday);
params.put("EMAILADDR", user);
params.put("FIRSTNAME", firstName);
params.put("LASTNAME", lastName);
params.put("GENDER", gender);
params.put("metaparameter_checkboxes", "REMEMBERME");
params.put("POSTALCODE", "92131");
params.put("REMEMBERME", "1");
params.put("path", path);
RequestBuilder rb = new RequestBuilder();
rb.method(HttpPost.METHOD_NAME).uri(uri).paramMap(params).encoding("UTF-8");
rsp = session.execute(rb);
HttpClientUtils.saveToFile(rsp.getEntity(), AppUtils.getTempFilePath("modifyProfileResult.html"));
String location = null;
if(rsp.getStatusLine().getStatusCode() == 302)
{
Header locHeader = rsp.getLastHeader("Location");
if(locHeader != null)
{
location = locHeader.getValue();
}
}
log.info(String.format("Modify profile result: StatusCode=[%d], Location=[%s]", rsp
.getStatusLine().getStatusCode(), location));
if(location != null)
{
uri = uri.resolve(location);
rsp = session.execute(new RequestBuilder().uri(uri));
HttpClientUtils.saveToFile(rsp.getEntity(), AppUtils.getTempFilePath("modifyProfileRedir.html"));
}
return (rsp.getStatusLine().getStatusCode() == 302) && (location != null);
}
private String getLoginUserName() throws IOException, ParseException
{
String userNameRegex = "userName: '(.*?)',";
String userName = MiscUtils.getRegexValueOnce(profileContent, userNameRegex, 1);
if(userName.trim().isEmpty())
{
log.info("userName is empty");
return null;
}
String loggedInRegex = "loggedIn: '(.*?)',";
String loggedIn = MiscUtils.getRegexValueOnce(profileContent, loggedInRegex, 1);
if(loggedIn.trim().isEmpty())
{
log.info("loggedIn is empty");
return null;
}
if(!"1".equals(loggedIn.trim()))
{
log.info("invalid loggedIn: [" + loggedIn + "].");
return null;
}
return userName.trim();
}
private void updateCookie(Map<String, String> resultMap)
{
String[] names = { "urs_sessionId", "purs_1", "surs_1", "curs_gigya_linked",
"curs_gigya_appid", "curs_fb_linked" };
for(int i = 0; i < names.length; i++)
{
updateCookie(names[i], resultMap);
resultMap.remove(names[i]);
}
String key = null;
for(Iterator<String> iter = resultMap.keySet().iterator(); iter.hasNext();)
{
key = iter.next();
if(key.contains("_tt_machines"))
{
break;
}
}
if(key != null)
{
updateCookie(key, resultMap);
resultMap.remove(key);
}
}
private void updateCookie(String cookieName, Map<String, String> resultMap)
{
Cookie cookie = createCookie(cookieName, resultMap.get(cookieName));
session.getCookieStore().addCookie(cookie);
}
private BasicClientCookie createCookie(String name, String value)
{
BasicClientCookie cookie = new BasicClientCookie(name, value);
cookie.setVersion(0);
cookie.setDomain(".cnet.com");
cookie.setPath("/");
cookie.setExpiryDate(null);
return cookie;
}
private String parseLoginResult(String jsonText, Map<String, String> resultMap)
{
JSONObject root = (JSONObject) JSONSerializer.toJSON(jsonText);
JSONObject rsp = root.getJSONObject("RpsResponse");
JSONObject status = rsp.getJSONObject("Status");
String state = status.getString("@state");
// Failed
if("failed".equals(state))
{
return status.getJSONObject("Error").getJSONObject("ErrorMessage").getString("$");
}
JSONObject user = rsp.getJSONObject("User");
// Successfully
if(!"processed".equals(state) || user == null)
{
return "Unkown state: " + state + ", user = " + user;
}
status = user.getJSONObject("Status");
int code = status.getInt("@code");
String codeStr = status.getString("$");
if(code != 0 || !"Authenticated".equals(codeStr))
{
return "Unkown user status code: " + code + ", codeStr = " + codeStr;
}
String name, value;
// purs_1
JSONObject permToken = user.getJSONObject("PermToken");
name = permToken.getString("@name");
value = permToken.getString("$");
resultMap.put(name, value);
// surs_1
JSONObject sessToken = user.getJSONObject("SessToken");
name = sessToken.getString("@name");
value = sessToken.getString("$");
resultMap.put(name, value);
// urs_sessionId
JSONObject sessionId = user.getJSONObject("SessionId");
resultMap.put("urs_sessionId", sessionId.getString("$"));
// RegistrationId
String regId = user.getJSONObject("RegistrationId").getString("$");
resultMap.put(regId + "_tt_machines", "false");
resultMap.put("WRUID", "0");
resultMap.put("MAD_INTERNAL", "0");
resultMap.put("curs_gigya_linked", "false");
resultMap.put("curs_gigya_appid", "259");
resultMap.put("curs_fb_linked", "false");
resultMap.put("cnet_joinCallout", "1");
resultMap.put("mad_rsi_segs", "ASK05540_10619&ASK05540_10648");
return null;
}
public static void main(String[] args)
{
String user = AppConfig.getInstance().getPropInput("cnet.user");
String password = AppConfig.getInstance().getPropInput("cnet.password");
for(int i = 0; args != null && i < args.length; i++)
{
if(args[i].startsWith("-user="))
{
user = args[i].substring("-user=".length());
}
else if(args[i].startsWith("-password="))
{
password = args[i].substring("-password=".length());
}
}
log.info(String.format("user=%s, password=%s", user, password));
CnetUser cnet = new CnetUser(user, password);
cnet.get();
}
}