package com.zdcf.service.Impl;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Serializable;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.io.FilenameUtils;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.zdcf.base.Constants;
import com.zdcf.dao.TwitterMediaMapper;
import com.zdcf.dao.TwitterPostMapper;
import com.zdcf.dao.TwitterPostSearchMapper;
import com.zdcf.dao.TwitterSearchHistoryMapper;
import com.zdcf.dao.TwitterUserMapper;
import com.zdcf.dao.customize.CustomizeTwitterPostMapper;
import com.zdcf.dao.customize.CustomizeTwitterSearchHistoryMapper;
import com.zdcf.mapper.Plugin;
import com.zdcf.model.TwitterMedia;
import com.zdcf.model.TwitterMediaExample;
import com.zdcf.model.TwitterPost;
import com.zdcf.model.TwitterPostSearch;
import com.zdcf.model.TwitterSearchHistory;
import com.zdcf.model.TwitterSearchHistoryExample;
import com.zdcf.model.TwitterUser;
import com.zdcf.service.TwitterSearchService;
import com.zdcf.tool.DateUtil;
import com.zdcf.tool.PageVo;
import com.zdcf.tool.ProxyUtil;
import com.zdcf.tool.StringUtil;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import oauth.signpost.OAuthConsumer;
import oauth.signpost.commonshttp.CommonsHttpOAuthConsumer;
import oauth.signpost.exception.OAuthCommunicationException;
import oauth.signpost.exception.OAuthExpectationFailedException;
import oauth.signpost.exception.OAuthMessageSignerException;
@Service
@Transactional
public class TwitterSearchServiceImpl implements TwitterSearchService {
@Autowired
private TwitterPostMapper twitterPostMapper;
@Autowired
private TwitterSearchHistoryMapper twitterSearchHistoryMapper;
@Autowired
private TwitterPostSearchMapper twitterPostSearchMapper;
@Autowired
private TwitterMediaMapper twitterMediaMapper;
@Autowired
private CustomizeTwitterPostMapper customizeTwitterPostMapper;
@Autowired
private CustomizeTwitterSearchHistoryMapper customizeTwitterSearchHistoryMapper;
@Autowired
private TwitterUserMapper twitterUserMapper;
@Autowired
private Plugin plugin;
public int insert(TwitterPost twitterPost){
int count = twitterPostMapper.insert(twitterPost);
return count;
}
@Override
public TwitterPost findById(Long id){
return twitterPostMapper.selectByPrimaryKey(id);
}
@Override
public Serializable getListPage(
PageVo<Map<String, Object>> pageVo,TwitterSearchHistory tsh) {
int offset = pageVo.getCurrentPage() - 1;
if (offset < 0)
offset = 0;
List<Map<String, Object>> list = customizeTwitterSearchHistoryMapper
.getListPage( offset * pageVo.getPageSize(),
pageVo.getPageSize(),tsh);
int count = customizeTwitterSearchHistoryMapper.getCount(tsh);
pageVo.setVoList(list);
pageVo.setRecordCount(count);
return pageVo;
}
@Override
public Map<String, Object> check(TwitterSearchHistory tsh) throws RuntimeException, OAuthMessageSignerException, OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException, IOException{
Map<String, Object> map =new HashMap<String, Object>();
//检查是否已经搜索过此内容或用户
TwitterSearchHistoryExample example = new TwitterSearchHistoryExample();
example.createCriteria().andSearchKeyEqualTo(tsh.getSearchKey())
.andSearchTypeEqualTo(tsh.getSearchType());
List<TwitterSearchHistory> list =twitterSearchHistoryMapper.selectByExample(example);
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd");
if(null!=list&&list.size()>0){
tsh =list.get(0);
}
if(null!=list&&list.size()>0&&sdf.format(list.get(0).getSearchDate()).compareTo(sdf.format(new Date()))==0){
map.put("searchId", tsh.getId());
map.put("status", Boolean.TRUE);
}else{
//今天没有搜索过,则调用推特api查询数据
map = this.addTwitterPostByKey(tsh);
}
return map;
}
protected Map<String, Object> addTwitterPostByKey(TwitterSearchHistory tsh) throws OAuthMessageSignerException, OAuthExpectationFailedException, OAuthCommunicationException, ClientProtocolException, IOException{
OAuthConsumer consumer = new CommonsHttpOAuthConsumer(
Constants.ConsumerKey,
Constants.ConsumerSecret);
Map<String, Object> map =new HashMap<String, Object>();
consumer.setTokenWithSecret(Constants.AccessToken, Constants.AccessSecret);
StringBuffer sb = new StringBuffer();
HttpClient client = ProxyUtil.getHttpClient();
HttpGet httpGet =null;
if(Constants.TWITTER_SEARCH_TYPE.SEARCH_USER.equals(tsh.getSearchType())){
httpGet = new HttpGet(Constants.TWITTER_USER_TIME_LINE+"?cursor=-1&count=200&screen_name="+tsh.getSearchKey());
}else{
httpGet = new HttpGet(Constants.TWITTER_SEARCH_TWEETS+"?cursor=-1&q="+tsh.getSearchKey()+"&count=100");
}
consumer.sign(httpGet);
HttpResponse response = client.execute(httpGet);
if(200!=response.getStatusLine().getStatusCode()){
Long remain = Long.valueOf(response.getAllHeaders()[9].getValue())/1000;
System.out.println("调用超过限制,请等待"+remain+"秒");
map.put("status", Boolean.FALSE);
map.put("msg", "当前搜索超过限制,请等待"+remain+"秒"+"或者尝试按照另一个类别搜索");
return map;
}
Header[] headers = response.getAllHeaders();
System.out.println("剩余次数:"+headers[18].getValue());//调用剩余次数
HttpEntity entry = response.getEntity();
if(entry != null)
{
InputStreamReader is = new InputStreamReader(entry.getContent());
BufferedReader br = new BufferedReader(is);
String str = null;
while((str = br.readLine()) != null)
{
sb.append(str.trim());
}
br.close();
}
//允许插入emoji
plugin.setNamesUtf8mb4();
JSONArray jsonArray = null;
JSONArray mediaArray = null;
JSONObject jsonObject=null;
JSONObject userObject=null;
TwitterPost twitterPost = new TwitterPost();
TwitterUser twitteruser =new TwitterUser();
TwitterMedia twitterMedia =new TwitterMedia();
if(Constants.TWITTER_SEARCH_TYPE.SEARCH_USER.equals(tsh.getSearchType())){
jsonArray = JSONArray.fromObject(sb.toString());
}else{
jsonArray = JSONObject.fromObject(sb.toString()).getJSONArray("statuses");
}
//有此搜索记录则不添加,更新搜索日期
tsh.setSearchDate(new Date());
if(null!=tsh.getId()){
twitterSearchHistoryMapper.updateByPrimaryKey(tsh);
}else{
twitterSearchHistoryMapper.insert(tsh);
}
map.put("searchId", tsh.getId());
TwitterPostSearch twitterPostSearch =new TwitterPostSearch();
for(int i=0,length=jsonArray.size();i<length;i++){
jsonObject = jsonArray.getJSONObject(i);
userObject = jsonObject.getJSONObject("user");
if(jsonArray.getJSONObject(i).getJSONObject("entities").containsKey("media"))
mediaArray =jsonArray.getJSONObject(i).getJSONObject("entities").getJSONArray("media");
//帖子有则不插入
if(null==twitterPostMapper.selectByPrimaryKey(jsonObject.getLong("id"))){
twitterPost.setId(jsonObject.getLong("id"));
twitterPost.setText(jsonObject.getString("text"));
twitterPost.setCreateAt(new Date(jsonObject.getString("created_at")));
twitterPost.setPostType(Constants.TWITTER_POST_TYPE.SEARCH_RESULT);
twitterPost.setUserId(userObject.getLong("id"));
twitterPostMapper.insert(twitterPost);
//增加到搜索结果记录
twitterPostSearch.setPostId(twitterPost.getId());
twitterPostSearch.setSearchId(tsh.getId());
twitterPostSearchMapper.insert(twitterPostSearch);
}
//用户有则不添加
if(null==twitterUserMapper.selectByPrimaryKey(userObject.getLong("id"))){
twitteruser.setId(userObject.getLong("id"));
twitteruser.setScreenName(userObject.getString("screen_name"));
twitteruser.setName(userObject.getString("name"));
twitteruser.setDescription(userObject.getString("description"));
twitteruser.setLocation(userObject.getString("location"));
twitteruser.setAvatar(userObject.getString("profile_image_url"));
twitterUserMapper.insert(twitteruser);
}
//图片、视频有则不添加
if(null!=mediaArray&&mediaArray.size()>0){
for(int j=0;j<mediaArray.size();j++){
if(null==twitterMediaMapper.selectByPrimaryKey(mediaArray.getJSONObject(j).getLong("id"))){
twitterMedia.setId(mediaArray.getJSONObject(j).getLong("id"));
twitterMedia.setMediaUrl(mediaArray.getJSONObject(j).getString("media_url"));
twitterMedia.setPostId(jsonObject.getLong("id"));
twitterMedia.setWidth(mediaArray.getJSONObject(j).getJSONObject("sizes").getJSONObject("small").getInt("w"));
twitterMedia.setHeight(mediaArray.getJSONObject(j).getJSONObject("sizes").getJSONObject("small").getInt("h"));
if(jsonArray.getJSONObject(i).containsKey("extended_entities")
&&jsonArray.getJSONObject(i).getJSONObject("extended_entities").containsKey("media")
&&jsonArray.getJSONObject(i).getJSONObject("extended_entities").getJSONArray("media").getJSONObject(0).containsKey("video_info")
&&jsonArray.getJSONObject(i).getJSONObject("extended_entities").getJSONArray("media").getJSONObject(0).getJSONObject("video_info").getJSONArray("variants").getJSONObject(0).containsKey("url")
&&FilenameUtils.getExtension(jsonArray.getJSONObject(i).getJSONObject("extended_entities").getJSONArray("media").getJSONObject(0).getJSONObject("video_info").getJSONArray("variants").getJSONObject(0).getString("url")).equals("mp4")){
twitterMedia.setVideoInfoUrl(jsonArray.getJSONObject(i).getJSONObject("extended_entities").getJSONArray("media").getJSONObject(0).getJSONObject("video_info").getJSONArray("variants").getJSONObject(0).getString("url"));
}
twitterMediaMapper.insert(twitterMedia);
}
}
}
}
map.put("status", Boolean.TRUE);
return map;
}
protected List<TwitterMedia> getMediaListByPostId(Long id){
TwitterMediaExample example = new TwitterMediaExample();
example.createCriteria().andPostIdEqualTo(id);
return twitterMediaMapper.selectByExample(example);
}
}