package tk.djcrazy.libCC98;
import android.app.Application;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.IOException;
import java.net.ConnectException;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.UnknownServiceException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.PatternSyntaxException;
import ch.boye.httpclientandroidlib.HttpEntity;
import ch.boye.httpclientandroidlib.HttpResponse;
import ch.boye.httpclientandroidlib.NameValuePair;
import ch.boye.httpclientandroidlib.ParseException;
import ch.boye.httpclientandroidlib.auth.AuthScope;
import ch.boye.httpclientandroidlib.auth.UsernamePasswordCredentials;
import ch.boye.httpclientandroidlib.client.ClientProtocolException;
import ch.boye.httpclientandroidlib.client.entity.UrlEncodedFormEntity;
import ch.boye.httpclientandroidlib.client.methods.HttpGet;
import ch.boye.httpclientandroidlib.client.methods.HttpPost;
import ch.boye.httpclientandroidlib.cookie.Cookie;
import ch.boye.httpclientandroidlib.entity.mime.MultipartEntity;
import ch.boye.httpclientandroidlib.entity.mime.content.FileBody;
import ch.boye.httpclientandroidlib.entity.mime.content.StringBody;
import ch.boye.httpclientandroidlib.impl.client.DefaultHttpClient;
import ch.boye.httpclientandroidlib.impl.cookie.BasicClientCookie;
import ch.boye.httpclientandroidlib.impl.cookie.BasicClientCookie2;
import ch.boye.httpclientandroidlib.message.BasicNameValuePair;
import ch.boye.httpclientandroidlib.util.EntityUtils;
import tk.djcrazy.MyCC98.application.MyApplication;
import tk.djcrazy.MyCC98.application.MyApplication.UsersInfo;
import tk.djcrazy.libCC98.data.LoginType;
import tk.djcrazy.libCC98.data.UserData;
import tk.djcrazy.libCC98.exception.CC98Exception;
import tk.djcrazy.libCC98.exception.NoUserFoundException;
import tk.djcrazy.libCC98.exception.ParseContentException;
import tk.djcrazy.libCC98.util.RegexUtil;
/**
* This class take care of the connection with CC98, keep the cookies and the
* user information.
*/
@Singleton
public class CC98ClientImpl implements ICC98Client {
public static final String TAG = CC98ClientImpl.class.getSimpleName();
@Inject
private ICC98UrlManager manager;
@Inject
private Application application;
@Override
public UserData getCurrentUserData() {
UserData userData = ((MyApplication) application).getCurrentUserData();
return userData;
}
private MyApplication getApplication() {
return (MyApplication) application;
}
@Override
public Bitmap getCurrentUserAvatar() {
return getApplication().getCurrentUserAvatar();
}
private DefaultHttpClient getHttpClient() {
return getApplication().mHttpClient;
}
@Override
public void clearLoginInfo() {
getHttpClient().getCookieStore().clear();
getHttpClient().getCredentialsProvider().clear();
}
@Override
public void pushNewPost(List<NameValuePair> pairList, String boardID) {
try {
HttpPost httpPost = new HttpPost(manager.getPushNewPostUrl(boardID));
httpPost.addHeader("Referer", manager.getPushNewPostReferer(boardID));
pairList.add(new BasicNameValuePair("username", getCurrentUserData()
.getUserName()));
pairList.add(new BasicNameValuePair("passwd", getCurrentUserData()
.getPassword16()));
httpPost.setEntity(new UrlEncodedFormEntity(pairList, "UTF-8"));
HttpResponse response = getHttpClient().execute(httpPost);
String responseString = EntityUtils.toString(response.getEntity());
if (StringUtils.isEmpty(responseString) || !responseString.contains("状态:发表帖子成功")) {
throw new CC98Exception("发帖失败");
}
} catch (Exception e) {
throw new CC98Exception(e.getMessage());
}
}
@Override
public void submitReply(List<NameValuePair> nvpsList, String boardID, String rootID) {
HttpPost httpPost = new HttpPost(manager.getSubmitReplyUrl(boardID));
httpPost.addHeader("Referer",
manager.getSubmitReplyReferer(boardID, rootID));
nvpsList.add(new BasicNameValuePair("username", getCurrentUserData()
.getUserName()));
nvpsList.add(new BasicNameValuePair("passwd", getCurrentUserData()
.getPassword16()));
try {
httpPost.setEntity(new UrlEncodedFormEntity(nvpsList, "UTF-8"));
HttpResponse response = getHttpClient().execute(httpPost);
String responseString = EntityUtils.toString(response.getEntity());
if (StringUtils.isEmpty(responseString)||!responseString.contains("状态:回复帖子成功")) {
throw new CC98Exception("回复失败");
}
} catch (Exception e) {
throw new CC98Exception(e.getMessage());
}
}
@Override
public String queryPosts(String keyWord, String sType, String searchDate,
int boardArea, String boardID) throws ParseException, IOException {
/*
* action: queryresult.asp name=keyword name=sType, value=2: 主题关键字搜索,
* value=1: 主题作者搜索 name=SearchDate, value=ALL: 所有日期, value=1: 昨天以来 ,
* value=5: 5天以来, value=10: 10天以来, value=30: 30天以来 name=boardarea,
* value=0: 全站搜索 name=boardid, name=serType, value=1: 所有帖子, value=2:
* 精华贴, value=3: 保存贴
*/
List<NameValuePair> nvpsList = new ArrayList<NameValuePair>();
HttpEntity entity;
HttpPost httpPost = new HttpPost(manager.getQueryUrl());
HttpResponse response = null;
String html = null;
httpPost.addHeader("Referer", manager.getQueryReferer());
nvpsList.add(new BasicNameValuePair("keyword", keyWord));
nvpsList.add(new BasicNameValuePair("sType", sType));
nvpsList.add(new BasicNameValuePair("SearchDate", searchDate));
nvpsList.add(new BasicNameValuePair("boardarea", String
.valueOf(boardArea)));
nvpsList.add(new BasicNameValuePair("serType", String.valueOf(boardID)));
httpPost.setEntity(new UrlEncodedFormEntity(nvpsList, "UTF-8"));
response = getHttpClient().execute(httpPost);
entity = response.getEntity();
if (entity != null) {
html = EntityUtils.toString(entity);
if (html.contains("搜索主题共查询到")) {
return html;
} else if (html.contains("没有找到您要查询的内容")) {
System.err.println("没有找到您要查询的内容!");
return "";
}
}
return null;
}
@Override
public String getPage(String link) {
try {
HttpResponse rsp = getHttpClient().execute( new HttpGet(link));
if (rsp.getStatusLine().getStatusCode() != 200) {
throw new CC98Exception("服务器有误!");
}
return EntityUtils.toString(rsp.getEntity());
} catch (Exception e) {
throw new CC98Exception(e.getMessage());
}
}
@Override
public String uploadPicture(File picFile)
throws PatternSyntaxException, MalformedURLException, IOException,
ParseContentException {
HttpPost post = new HttpPost(manager.getUploadPictureUrl());
MultipartEntity reqEntity = new MultipartEntity();
reqEntity.addPart("act", new StringBody("upload"));
reqEntity.addPart("fname", new StringBody(picFile.getName()));
reqEntity.addPart("file1", new FileBody(picFile));
post.setEntity(reqEntity);
HttpResponse response = getHttpClient().execute(post);
String sTotalString = EntityUtils.toString(response.getEntity());
if (response.getStatusLine().getStatusCode() != 200) {
Log.e(TAG, sTotalString);
throw new IllegalStateException("upload error");
}
return RegexUtil.getMatchedString(
CC98ParseRepository.UPLOAD_PIC_ADDRESS_REGEX, sTotalString)
.replace(",1", "");
}
@Override
public String getOutboxHtml(int pageNumber) throws ClientProtocolException,
ParseException, IOException {
return getPage(manager.getOutboxUrl(pageNumber));
}
@Override
public String getUserImgUrl(String userName)
throws ClientProtocolException, ParseException, IOException,
ParseContentException {
String html = getPage(manager.getUserProfileUrl(userName));
String url = RegexUtil.getMatchedString(
CC98ParseRepository.USER_PROFILE_AVATAR_REGEX, html);
if (!url.startsWith("http") && !url.startsWith("ftp")) {
url = getDomain() + url;
}
return url;
}
@Override
public void sendPm(String touser, String title, String message)
throws ClientProtocolException, IOException, CC98Exception {
HttpPost post = new HttpPost(manager.getSendPmUrl());
List<NameValuePair> msgInfo = new ArrayList<NameValuePair>();
msgInfo.add(new BasicNameValuePair("touser", touser));
msgInfo.add(new BasicNameValuePair("title", title));
msgInfo.add(new BasicNameValuePair("message", message));
post.setEntity(new UrlEncodedFormEntity(msgInfo, "UTF-8"));
HttpResponse response = getHttpClient().execute(post);
HttpEntity entity = response.getEntity();
if (entity == null
|| !EntityUtils.toString(response.getEntity()).contains(
"发送短信息成功")) {
Log.d(TAG, EntityUtils.toString(response.getEntity()));
throw new CC98Exception("send pm failed, reply content is: "
+ EntityUtils.toString(response.getEntity()));
}
}
@Override
public void addFriend(String userId) throws ParseException,
NoUserFoundException, IOException {
if (userId == null) {
throw new IllegalArgumentException("Null argument!");
}
HttpPost httpPost = new HttpPost(manager.getAddFriendUrl());
httpPost.addHeader("Referer", manager.getAddFriendUrlReferrer());
List<NameValuePair> nvpsList = new ArrayList<NameValuePair>();
nvpsList.add(new BasicNameValuePair("todo", "saveF"));
nvpsList.add(new BasicNameValuePair("touser", userId));
nvpsList.add(new BasicNameValuePair("Submit", "保存"));
httpPost.setEntity(new UrlEncodedFormEntity(nvpsList, "UTF-8"));
HttpResponse response = getHttpClient().execute(httpPost);
if (response.getStatusLine().getStatusCode() != 200) {
throw new ConnectException("服务器返回错误!");
}
HttpEntity entity = response.getEntity();
if (entity != null) {
String html = EntityUtils.toString(entity);
if (html.contains("好友添加成功")) {
return;
} else if (html.contains("论坛没有这个用户,操作未成功")) {
throw new NoUserFoundException("不存在此用户!");
} else {
throw new UnknownServiceException("未知错误!");
}
} else {
throw new ConnectException("服务器返回错误!");
}
}
@Override
public Bitmap getBitmapFromUrl(String url) throws CC98Exception {
try {
HttpGet get = new HttpGet(url);
HttpResponse response = getHttpClient().execute(get);
return BitmapFactory.decodeStream(response.getEntity().getContent());
} catch (Exception e) {
throw new CC98Exception(e.getMessage());
}
}
@Override
public Bitmap getUserImg(String userName) throws ClientProtocolException,
ParseException, IOException, ParseContentException {
return getBitmapFromUrl(getUserImgUrl(userName));
}
private Bitmap getLoginUserImgAndGender(UserData userData2, LoginType type) {
try {
String html = getPage(manager.getUserProfileUrl(type,
userData2.getUserName()));
String url = RegexUtil.getMatchedString(
CC98ParseRepository.USER_PROFILE_AVATAR_REGEX, html);
if (!url.startsWith("http") && !url.startsWith("ftp")) {
url = manager.getClientUrl(type) + url;
}
return getBitmapFromUrl(url);
} catch (Exception e) {
return BitmapFactory
.decodeFile("file:///android_asset/pic/no_avatar.jpg");
}
}
public void addHttpBasicAuthorization(String authName,
String authPassword) {
try {
URI uri = new URI(getDomain(LoginType.USER_DEFINED));
getHttpClient().getCredentialsProvider().setCredentials(
new AuthScope(uri.getHost(), uri.getPort(),
AuthScope.ANY_SCHEME),
new UsernamePasswordCredentials(authName, authPassword));
} catch (URISyntaxException e) {
throw new CC98Exception("Invalid Uri problem");
}
}
@Override
public String getDomain() {
return manager.getClientUrl();
}
@Override
public String getDomain(LoginType type) {
return manager.getClientUrl(type);
}
@Override
public List<Bitmap> getUserAvatars() {
return ((MyApplication) application).getUserAvatars();
}
@Override
public UsersInfo getUsersInfo() {
return ((MyApplication) application).getUsersInfo();
}
@Override
public void switchToUser(int index) {
getUsersInfo().currentUserIndex = index;
getApplication().storeUsersInfo();
getApplication().syncUserDataAndHttpClient();
}
@Override
public void deleteUserInfo(int pos) {
if (pos != getUsersInfo().currentUserIndex) {
Log.d(TAG, "to delete:" + pos);
UsersInfo info = getUsersInfo();
List<Bitmap> avatars = getUserAvatars();
UserData currentUser = getCurrentUserData();
info.users.remove(pos);
avatars.remove(pos);
int newPos = info.users.indexOf(currentUser);
info.currentUserIndex = newPos;
getApplication().storeUsersInfo();
}
}
}