package com.lgq.rssreader.parser;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.ParseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.SharedPreferences;
import android.text.Html;
import android.text.TextUtils;
import android.util.Log;
import com.lgq.rssreader.R;
import com.lgq.rssreader.dal.SyncStateDalHelper;
import com.lgq.rssreader.entity.SyncState;
import com.lgq.rssreader.core.Config;
import com.lgq.rssreader.core.ReaderApp;
import com.lgq.rssreader.entity.Blog;
import com.lgq.rssreader.entity.Channel;
import com.lgq.rssreader.entity.Profile;
import com.lgq.rssreader.entity.Result;
import com.lgq.rssreader.entity.Subscription;
import com.lgq.rssreader.entity.Tag;
import com.lgq.rssreader.entity.Unread;
import com.lgq.rssreader.entity.UnReadCount;
import com.lgq.rssreader.enums.RssAction;
import com.lgq.rssreader.enums.SyncType;
import com.lgq.rssreader.enums.Token;
import com.lgq.rssreader.formatter.BlogFormatter;
import com.lgq.rssreader.utils.Helper;
import com.lgq.rssreader.utils.HtmlHelper;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.JsonHttpResponseHandler;
import com.loopj.android.http.RequestParams;
public class FeedlyParser extends RssParser {
public FeedlyParser()
{
this.Preferences = ReaderApp.getPreferences();
this.editor = Preferences.edit();
}
//Const Title
private static final String RECOMMENDTITLE = "pop/topic/top/language/";
public static final String READLISTTITLE = "user/-/state/com.google/reading-list";
public static final String STARREDTTITLE = "user/-/state/com.google/starred";
//Feedly Urls and Login Auth
private static final String AUTH_PARAMS = "accountType=HOSTED_OR_GOOGLE&Email={0}&Passwd={1}&service=reader&source=mobilescroll";
private static final String FEEDLY_AUTH_PARAMS = "code={0}&client_id=feedly&client_secret=0XP4XQ07VVMDWBKUHTJM4WUQ&redirect_uri=http%3A%2F%2Fdev.feedly.com%2Ffeedly.html&grant_type=authorization_code";
private static final String LOGINURL = "https://www.google.com/accounts/ClientLogin";
public static final String FEEDLYLOGINURL = "http://cloud.feedly.com/v3/auth/token";
private static final String SUBSCRIPTIONURL = "http://cloud.feedly.com/v3/subscriptions?ct=feedly.desktop";
private static final String PROFILEURL = "http://cloud.feedly.com/v3/profile";
private static final String TAGURL = "http://cloud.feedly.com/v3/tags?ct=feedly.desktop";
private static final String UNREADURL = "http://cloud.feedly.com/v3/markers/counts?ct=feedly.desktop";
private static final String EDITTAGURL = "http://cloud.feedly.com/v3/markers?ck=1371868985337&ct=feedly.desktop";
private static final String EDITSUBSCRIPTIONURL = "https://cloud.feedly.com/reader/api/0/subscription/edit?client=scroll";
private static final String RENAMETAGURL = "https://cloud.feedly.com/reader/api/0/rename-tag?client=scroll";
private static final String MARKALLASREADURL = "https://cloud.feedly.com/reader/api/0/mark-all-as-read?client=scroll";
private static final String DISABLETAGURL = "https://cloud.feedly.com/reader/api/0/disable-tag?client=scroll";
private static final String ADDSUBSURL = "https://cloud.feedly.com/reader/api/0/subscription/quickadd";
private static final String ADDSEARCHRESULTURL = "https://cloud.feedly.com/reader/api/0/subscription/edit?source=FEED_FINDER_SEARCH_RESULT&client=scroll";
private static final String SEARCHSUBSURL = "https://cloud.feedly.com/reader/directory/search?q={0}&ck={1}&client=scroll&start={2}";
private static final String SYNCUNREADURL = "https://cloud.feedly.com/reader/atom/user/-/state/com.google/read?n=1000";
private static final String SORTLISTURL = "https://cloud.feedly.com/reader/api/0/preference/stream/list?output=json";
// 获取img标签正则
private static final String IMGURL_REG = "<img.*src=(.*?)[^>]*?>";
// 获取src路径的正则
private static final String IMGSRC_REG = "http:\"?(.*?)(\"|>|\\s+)";
// Tags, Subscription, SortOrder and Unread
private List<Tag> Tags;
private List<Subscription> Subscriptions;
private List<String> SortList;
private Unread Unreads;
private List<Channel> channels;
private SharedPreferences.Editor editor;
@Override
public List<Channel> getChannels() {
// TODO Auto-generated method stub
//lazy load data
if (channels != null && channels.size() > 0)
return channels;
if (Tags != null && Unreads != null && Subscriptions != null && SortList != null)
{
List<Channel> obj = new ArrayList<Channel>();
for(Tag t: Tags){
Channel c = new Channel();
c.Id = t.Id;
c.Title = t.Label;
c.SortId = t.SortId;
c.IsDirectory = true;
c.Children = new ArrayList<Channel>();
UnReadCount uc = Helper.findUnreadById(Unreads, t.Id);
if(uc != null){
c.LastUpdateTime = uc.NewestItemStamp;
c.UnreadCount = uc.Count;
}else{
c.LastUpdateTime = new Date();
c.UnreadCount = 0;
}
obj.add(c);
}
for(Subscription s : Subscriptions)
{
Channel c = new Channel();
c.Id = s.Id;
c.Title = s.Title;
c.SortId = s.SortId;
c.IsDirectory = false;
c.Children = new ArrayList<Channel>();
UnReadCount uc = Helper.findUnreadById(Unreads, s.Id);
if(uc != null){
c.LastUpdateTime = uc.NewestItemStamp;
c.UnreadCount = uc.Count;
}else{
c.LastUpdateTime = new Date();
c.UnreadCount = 0;
}
if (s.Categories.size() != 0)
{
c.IsDirectory = false;
for(Tag t : s.Categories)
{
Channel d = Helper.findChannelById(obj, t.Id);
if (d != null)
{
d.Children.add(c);
}
}
}
else
{
obj.add(c);
}
}
Integer i = 0;
for(Channel displayObj : obj)
{
displayObj.Folder = i.toString();
displayObj.SortId = i.toString();
i++;
if (displayObj.Children != null)
{
for(Channel display : displayObj.Children)
{
display.Folder = i.toString();
display.SortId = i.toString();
i++;
}
}
}
//new add rss feeds will not dispear in sortlist
ArrayList<Channel> newFeeds = new ArrayList<Channel>();
for(Channel c : obj){
if(!SortList.contains(c.Title))
newFeeds.add(c);
}
channels = new ArrayList<Channel>();
for(String sortId : SortList)
{
for(Channel c : obj){
if (c.Title.equals(sortId)){
channels.add(c);
break;
}
}
}
channels.addAll(newFeeds);
}
return channels;
}
@Override
public void connect(String username, String password) {
// TODO Auto-generated method stub
}
public void refreshToken(final HttpResponseHandler handler){
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
String params = "client_id=feedly&client_secret=0XP4XQ07VVMDWBKUHTJM4WUQ&" +
"grant_type=refresh_token&refresh_token=" + ReaderApp.getToken(Token.RefreshToken);
StringEntity se = null;
try {
se = new StringEntity(params.toString(),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return;
}
client.post(null, FEEDLYLOGINURL, se, "application/x-www-form-urlencoded", new JsonHttpResponseHandler(){
public void onFailure(final Throwable t, final String error){
new Thread(){
public void run(){
String result = "";
if(error != null){
result = error;
}else{
result = t.getCause().getMessage();
}
Log.e("RssReader", result);
handler.onCallback("", false, result);
}
}.start();
}
public void onSuccess(final JSONObject result){
new Thread(){
public void run(){
try {
ReaderApp.setToken(Token.AccessToken, result.getString("access_token"));
handler.onCallback(result.getString("access_token"), true, "");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
handler.onCallback("", false, e.getMessage());
}
}
}.start();
}
});
}
@Override
public void loadData(List<SyncState> states, HttpResponseHandler handler) {
getSubsciptions(handler);
getUnReadCount(handler);
getSortList(handler);
getProfile(handler);
syncFromFeedly(handler);
syncToFeedly(states,handler);
}
private void getProfile(final HttpResponseHandler handler) {
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
client.get(PROFILEURL, new JsonHttpResponseHandler(){
public void onFailure(final Throwable e, final String errorResponse){
new Thread(){
public void run(){
String error = "";
if(errorResponse == null)
error = e.getCause().getMessage();
else
error = errorResponse;
if (error != null && error.contains("expire")){
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
getProfile(handler);
}else{
if (handler != null)
{
handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetprofile));
}
}
}
});
Log.e("RssReader", error);
}
else
{
if (handler != null)
{
handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetprofile));
}
}
}
}.start();
}
public void onSuccess(final JSONObject result){
new Thread(){
public void run(){
try
{
Profile p = new Profile();
// client: "feedly"
// created: 1412954194833
// dropboxConnected: false
// email: "redelva2008@163.com"
// evernoteConnected: false
// facebookConnected: false
// familyName: "陆"
// fullName: "陆国庆"
// givenName: "国庆"
// id: "5cdfeb7c-78fa-4389-a3ef-9e8edd496de9"
// locale: "en_US"
// paymentProviderId: {}
// paymentSubscriptionId: {}
// picture: "https://apis.live.net/v5.0/e532156f3145db48/picture"
// pocketConnected: false
// source: "feedly.desktop 24.0.861"
// twitterConnected: false
// wave: "2014.41"
// windowsLiveConnected: true
// windowsLiveId: "e532156f3145db48"
// wordPressConnected: false
p.Email = result.getString("email");
p.FamilyName = result.getString("familyName");
p.Gender = result.has("gender") ? result.getString("gender") : "";
p.GivenName = result.getString("givenName");
//p.Google = result.getString("google");
if(result.has("google"))
p.Account = "Google";
if(result.getBoolean("evernoteConnected"))
p.Account = "Evernote";
if(result.getBoolean("facebookConnected"))
p.Account = "Facebook";
if(result.getBoolean("twitterConnected"))
p.Account = "Twitter";
if(result.getBoolean("windowsLiveConnected"))
p.Account = "WindowsLive";
if(result.getBoolean("pocketConnected"))
p.Account = "Pocket";
if(result.getBoolean("wordPressConnected"))
p.Account = "WordPress";
p.Id = result.getString("id");
p.Locale = result.getString("locale");
p.Picture = result.getString("picture").replace("?sz=50", "?sz=420");
p.Reader = result.has("reader") ?result.getString("reader") : "";
p.Wave = result.getString("wave");
ReaderApp.setProfile(p);
if (handler != null)
{
handler.sendResponseMessage(p, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successtogetprofile));
}
}catch(JSONException e){
e.printStackTrace();
Log.i("RssReader", "Error Happen Profile" + e.getMessage());
}
}
}.start();
}
});
}
private void syncToFeedly(List<SyncState> unsync, HttpResponseHandler handler){
if(unsync == null || unsync.size() == 0)
return ;
//seperate blog and channel type first
final List<String> readblogs = new ArrayList<String>();
final List<String> unreadblogs = new ArrayList<String>();
final List<String> starblogs = new ArrayList<String>();
final List<String> unstarblogs = new ArrayList<String>();
final List<SyncState> channels = new ArrayList<SyncState>();
for(SyncState state : unsync){
if(state.BlogOriginId != null && state.BlogOriginId.length() > 0){
if(state.Status == RssAction.AsRead)
readblogs.add(state.BlogOriginId);
if(state.Status == RssAction.AsUnread)
unreadblogs.add(state.BlogOriginId);
if(state.Status == RssAction.AsStar)
starblogs.add(state.BlogOriginId);
if(state.Status == RssAction.AsUnstar)
unstarblogs.add(state.BlogOriginId);
}
if(state.ChannelId != null && state.ChannelId.length() > 0){
channels.add(state);
}
}
//use batchMarkTag for blog
batchMarkTag(readblogs, RssAction.AsRead, new HttpResponseHandler(){
@Override
public <RssAction> void onCallback(RssAction action, boolean result, String msg){
if(result){
Log.i("RssReader", msg);
SyncStateDalHelper helper = new SyncStateDalHelper();
helper.Delete(readblogs, SyncType.Blog);
helper.Close();
}
}
});
batchMarkTag(unreadblogs, RssAction.AsUnread, new HttpResponseHandler(){
@Override
public <RssAction> void onCallback(RssAction action, boolean result, String msg){
if(result){
Log.i("RssReader", msg);
SyncStateDalHelper helper = new SyncStateDalHelper();
helper.Delete(unreadblogs, SyncType.Blog);
helper.Close();
}
}
});
batchMarkTag(starblogs, RssAction.AsStar, new HttpResponseHandler(){
@Override
public <RssAction> void onCallback(RssAction action, boolean result, String msg){
if(result){
Log.i("RssReader", msg);
SyncStateDalHelper helper = new SyncStateDalHelper();
helper.Delete(starblogs, SyncType.Blog);
helper.Close();
}
}
});
batchMarkTag(unstarblogs, RssAction.AsUnstar, new HttpResponseHandler(){
@Override
public <RssAction> void onCallback(RssAction action, boolean result, String msg){
if(result){
Log.i("RssReader", msg);
SyncStateDalHelper helper = new SyncStateDalHelper();
helper.Delete(unstarblogs, SyncType.Blog);
helper.Close();
}
}
});
//single for channel
}
private void getSubsciptions(final HttpResponseHandler handler){
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
client.get(SUBSCRIPTIONURL + "&ck=" + System.currentTimeMillis(), new JsonHttpResponseHandler(){
@Override
public void onFailure(final Throwable e, final String errorResponse){
new Thread(){
public void run(){
String error = "";
if(errorResponse == null)
error = e.getCause().getMessage();
else
error = errorResponse;
if (error != null && error.contains("expire")){
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
getSubsciptions(handler);
}else{
if (handler != null)
{
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogettags));
}
}
}
});
Log.e("RssReader", error);
}
else
{
if (handler != null)
{
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogettags));
}
}
}
}.start();
}
public void onSuccess(final JSONArray items){
new Thread(){
public void run(){
try
{
List<Tag> tags = new ArrayList<Tag>();
for(int i=0; i < items.length(); i++)
{
if(items.getJSONObject(i).has("categories"))
{
Tag t = new Tag();
JSONArray categories = items.getJSONObject(i).getJSONArray("categories");
JSONObject node = null;
for(int j=0; j< categories.length();j++)
{
if(categories.getJSONObject(j).get("id") != null)
{
node = categories.getJSONObject(j);
t.Id = node.getString("id");
t.Label = node.getString("label");
if (!tags.contains(t))
tags.add(t);
}
}
}
}
Tags = tags;
Log.i("RssReader", "Finish tags");
if (handler != null)
{
handler.sendResponseMessage(null, null, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successtogettags));
}
List<Subscription> subs = new ArrayList<Subscription>();
for(int i=0; i< items.length();i++)
{
Subscription s = new Subscription();
JSONObject subscription = items.getJSONObject(i);
s.Id = subscription.getString("id");
s.Title = subscription.getString("title");
s.Categories = new ArrayList<Tag>();
if (subscription.has("categories") && subscription.getJSONArray("categories").length() > 0)
{
JSONArray categories = subscription.getJSONArray("categories");
for(int j=0; j< categories.length(); j++)
{
JSONObject category = categories.getJSONObject(j);
Tag t = new Tag();
t.Id = category.getString("id");
t.Label = category.getString("label");
s.Categories.add(t);
}
}
if (subscription.has("updated"))
s.FirstItemMSEC = new Date(subscription.getLong("updated"));
else
s.FirstItemMSEC = new Date();
subs.add(s);
}
Subscriptions = subs;
if (handler != null)
{
handler.sendResponseMessage(null, null, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successtogetsubscriptions));
}
Log.i("RssReader", "Finish Subscriptions");
}
catch (JSONException e)
{
if (handler != null)
{
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetsubscriptions));
}
e.printStackTrace();
Log.i("RssReader", "Error Happen Subscriptions" + e.getMessage());
}
}
}.start();
}
});
}
public void getCount(final String feedId, final HttpResponseHandler handler){
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
//client.get(UNREADURL + "&ck=" + System.currentTimeMillis() + "&steamId=" + HtmlHelper.UrlEncodeUpper(feedId), new JsonHttpResponseHandler(){
client.get(UNREADURL + "&ck=" + System.currentTimeMillis() + "&steamId=" + URLEncoder.encode(feedId), new JsonHttpResponseHandler(){
@Override
public void onFailure(final Throwable e, final String errorResponse){
new Thread(){
public void run(){
String error = "";
if(errorResponse == null)
error = e.getCause().getMessage();
else
error = errorResponse;
if (error != null && error.contains("expire"))
{
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
getCount(feedId, handler);
}else{
if (handler != null)
{
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetunreadcounts));
}
}
}
});
Log.e("RssReader", error);
}
else
{
if (handler != null)
{
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetunreadcounts));
}
}
}
}.start();
}
public void onSuccess(final JSONObject root){
new Thread(){
public void run(){
try
{
for(int i=0, len=root.getJSONArray("unreadcounts").length(); i<len;i++){
JSONObject obj = root.getJSONArray("unreadcounts").getJSONObject(i);
if(obj.getString("id").equals(feedId)){
int count = obj.getInt("count");
if (handler != null)
{
handler.sendResponseMessage(count, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successtogetunreadcounts));
}
return;
}
}
if (handler != null)
{
handler.sendResponseMessage(-1, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetunreadcounts));
}
Log.i("RssReader","Finish unreadcount");
}
catch (Exception ex)
{
if (handler != null)
{
handler.sendResponseMessage(0, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetunreadcounts));
}
Log.i("RssReader","Error Happen unreadcount" + ex.getMessage());
}
}
}.start();
}
});
}
private void getUnReadCount(final HttpResponseHandler handler){
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
client.get(UNREADURL + "&ck=" + System.currentTimeMillis(), new JsonHttpResponseHandler(){
@Override
public void onFailure(final Throwable e, final String errorResponse){
new Thread(){
public void run(){
String error = "";
if(errorResponse == null)
error = e.getCause().getMessage();
else
error = errorResponse;
if (error != null && error.contains("expire")){
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
getUnReadCount(handler);
}else{
if (handler != null){
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetunreadcounts));
}
}
}
});
Log.e("RssReader", error);
}
else{
if (handler != null){
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetunreadcounts));
}
}
}
}.start();
}
public void onSuccess(final JSONObject root){
new Thread(){
public void run(){
try
{
Unread unRead = new Unread();
//unRead.Max = root["max"].Value<int>();
unRead.Unreads = new ArrayList<UnReadCount>();
JSONArray unreadcounts = root.getJSONArray("unreadcounts");
for(int i=0; i< unreadcounts.length();i++)
{
JSONObject count = unreadcounts.getJSONObject(i);
UnReadCount u = new UnReadCount();
u.Id = count.getString("id");
u.Count = count.getInt("count");
u.NewestItemStamp = new Date(count.getLong("updated"));
unRead.Unreads.add(u);
}
Unreads = unRead;
if (handler != null)
{
handler.sendResponseMessage(null, null, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successtogetunreadcounts));
}
Log.i("RssReader","Finish unreadcount");
}
catch (Exception ex)
{
if (handler != null)
{
handler.sendResponseMessage(null, null, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetunreadcounts));
}
Log.i("RssReader","Error Happen unreadcount" + ex.getMessage());
}
}
}.start();
}
});
}
private void getSortList(final HttpResponseHandler handler){
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
client.get("http://cloud.feedly.com/v3/preferences?ct=feedly.desktop&ck=" + System.currentTimeMillis(), new JsonHttpResponseHandler(){
@Override
public void onFailure(final Throwable e, final String errorResponse){
new Thread(){
public void run(){
String error = "";
if(errorResponse == null)
error = e.getCause().getMessage();
else
error = errorResponse;
if (error != null && error.contains("expire"))
{
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
getSortList(handler);
}else{
if (handler != null)
{
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetsortorder));
}
}
}
});
Log.e("RssReader", error);
}
else
{
if (handler != null)
{
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetsortorder));
}
}
}
}.start();
}
public void onSuccess(final JSONObject result){
new Thread(){
public void run(){
try{
if(result.has("categoriesOrdering"))
{
JSONArray orders = new JSONArray(result.getString("categoriesOrdering"));
SortList = new ArrayList<String>();
int length = orders.length();
for(int i = 0; i<length; i++){
SortList.add(orders.getString(i));
}
}
else
{
SortList = new ArrayList<String>();
}
if (handler != null)
{
handler.sendResponseMessage(null, null, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successtogetsortorder));
}
Log.i("RssReader", "Finish Sort List");
}
catch(Exception e){
if (handler != null)
{
handler.sendResponseMessage(null, null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetsortorder));
}
Log.i("RssReader", "Error Sort List" + e.getMessage());
}
}
}.start();
}
});
}
private void syncFromFeedly(final HttpResponseHandler handler)
{
String url = "http://cloud.feedly.com/v3/markers/reads";
Long lastTimeSync = Preferences.getLong("LastTimeSyncUnread", System.currentTimeMillis() - 24 * 60 *60 *1000);
url = url + "?newerThan=" + String.valueOf(lastTimeSync);
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
client.get(url, new JsonHttpResponseHandler(){
@Override
public void onFailure(final Throwable e, final String errorResponse){
new Thread(){
public void run(){
String error = "";
if(errorResponse == null)
error = e.getCause().getMessage();
else
error = errorResponse;
if (error != null && error.contains("expire")){
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
syncFromFeedly(handler);
}else{
// if (handler != null)
// {
// handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedsynctofeedly));
// }
}
}
});
Log.e("RssReader", error);
}
// else
// {
// if (handler != null)
// {
// handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedsynctofeedly));
// }
// }
}
}.start();
}
public void onSuccess(final JSONObject data){
new Thread(){
public void run(){
try {
List<String> entryIds = new ArrayList<String>();
for(int i=0, len=data.getJSONArray("entries").length(); i< len; i++){
entryIds.add(data.getJSONArray("entries").getString(i));
}
editor.putLong("LastTimeSyncUnread", System.currentTimeMillis()).commit();
if(handler != null && entryIds.size() > 0)
handler.sendResponseMessage(entryIds, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successsynctofeedly));
Log.i("RssReader", "Sync from feedly complete");
} catch (JSONException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if(handler != null)
handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedsynctofeedly));
}
}
}.start();
}
});
}
public void batchMarkTag(final List<String> blogs, final RssAction action, final HttpResponseHandler handler) {
if(blogs == null || blogs.size() == 0)
return;
String actionParams = "";
String method = "";
String url = "";
if (action == RssAction.AsStar)
{
url = "http://cloud.feedly.com/v3/tags/user%2F" + ReaderApp.getProfile().Id + "%2Ftag%2Fglobal.saved?ct=feedly.desktop";
method = "PUT";
StringBuffer sb = new StringBuffer();
for(String blog : blogs){
sb.append("\"" + blog + "\",");
}
if(sb.length() > 0 )
sb.deleteCharAt(sb.length() - 1);
actionParams = "{\"entryId\":[" + sb.toString() + "]}";
}
else if (action == RssAction.AsRead)
{
StringBuffer sb = new StringBuffer();
for(String blog : blogs){
sb.append("\"" + blog + "\",");
}
if(sb.length() > 0 )
sb.deleteCharAt(sb.length() - 1);
actionParams = "{\"action\":\"markAsRead\",\"type\":\"entries\",\"entryIds\":[" + sb.toString() + "]}";
method = "POST";
url = "http://cloud.feedly.com/v3/markers?ct=feedly.desktop";
}
else if (action == RssAction.AsUnread)
{
StringBuffer sb = new StringBuffer();
for(String blog : blogs){
sb.append("\"" + blog + "\",");
}
if(sb.length() > 0 )
sb.deleteCharAt(sb.length() - 1);
actionParams = "{\"action\":\"keepUnread\",\"type\":\"entries\",\"entryIds\":[" + sb.toString() + "]}";
method = "POST";
url = "http://cloud.feedly.com/v3/markers?ct=feedly.desktop";
}
url = url + "&ck=" + System.currentTimeMillis();
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
AsyncHttpResponseHandler async = new AsyncHttpResponseHandler(){
public void onSuccess(String response){
new Thread(){
public void run(){
if (handler != null)
{
handler.sendResponseMessage(action, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successupdatestatus));
}
}
}.start();
}
public void onFailure(final Throwable e, final String response) {
// Response failed :(
new Thread(){
public void run(){
String error = "";
if(response == null){
error = e.getCause().getMessage();
}else{
error = response;
}
if (error != null && error.contains("expire")){
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
batchMarkTag(blogs, action, handler);
}else{
if (handler != null){
handler.sendResponseMessage(action, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedupdatestatus));
}
}
}
});
Log.i("RssReader", error);
}
else
{
if (handler != null)
{
handler.sendResponseMessage(action, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedupdatestatus));
}
}
}
}.start();
}
};
if(actionParams.length() == 0)
{
client.addHeader("Content-Type","application/json");
client.addHeader("Content-Length","0");
client.delete(url,async);
}
else
{
StringEntity se = null;
try {
se = new StringEntity(actionParams.toString(),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return;
}
client.post(null, url, se, "application/json",async);
}
}
@Override
public void markTag(final Blog blog, final RssAction action, final HttpResponseHandler handler) {
String actionParams = "";
String method = "";
String url = "";
if (action == RssAction.AsUnstar)
{
try {//cloud.
url = "http://feedly.com/v3/tags/user%2F" + ReaderApp.getProfile().Id + "%2Ftag%2Fglobal.saved/" + URLEncoder.encode(blog.BlogId, "UTF-8") + "?ct=feedly.desktop";
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
method = "DELETE";
}
else if (action == RssAction.AsStar)
{//cloud.
url = "http://feedly.com/v3/tags/user%2F" + ReaderApp.getProfile().Id + "%2Ftag%2Fglobal.saved?ct=feedly.desktop";
method = "PUT";
actionParams = "{\"entryId\":\"" + blog.BlogId + "\"}";
}
else if (action == RssAction.AsRead)
{//cloud.
actionParams = "{\"action\":\"markAsRead\",\"type\":\"entries\",\"entryIds\":[\"" + blog.BlogId + "\"]}";
method = "POST";
url = "http://feedly.com/v3/markers?ct=feedly.desktop";
}
else if (action == RssAction.AsUnread)
{//cloud.
actionParams = "{\"action\":\"keepUnread\",\"type\":\"entries\",\"entryIds\":[\"" + blog.BlogId + "\"]}";
method = "POST";
url = "http://feedly.com/v3/markers?ct=feedly.desktop";
}
url = url + "&ck=" + System.currentTimeMillis();
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
AsyncHttpResponseHandler async = new AsyncHttpResponseHandler(){
public void onSuccess(String response){
new Thread(){
public void run(){
if (handler != null)
{
handler.sendResponseMessage(action, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successupdatestatus));
}
}
}.start();
}
public void onFailure(final Throwable e, final String response) {
// Response failed :(
new Thread(){
public void run(){
String error = "";
if(response == null){
error = e.getCause().getMessage();
}else{
error = response;
}
if (error != null && error.contains("expire")){
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
markTag(blog, action, handler);
}else{
if (handler != null){
handler.sendResponseMessage(action, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedupdatestatus));
}
}
}
});
Log.e("RssReader", error);
}
else
{
if (handler != null)
{
handler.sendResponseMessage(action, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedupdatestatus));
}
}
}
}.start();
}
};
if(method.equals("DELETE"))
{
client.addHeader("Content-Type","application/json");
client.addHeader("Content-Length","0");
client.delete(url,async);
}
else if(method.equals("POST"))
{
StringEntity se = null;
try {
se = new StringEntity(actionParams.toString(),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return;
}
client.post(null, url, se, "application/json",async);
}
else if(method.equals("PUT"))
{
StringEntity se = null;
try {
se = new StringEntity(actionParams.toString(),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return;
}
client.put(null, url, se, "application/json",async);
}
}
@Override
public void markTag(final Channel channel, final RssAction action, final HttpResponseHandler handler) {
// TODO Auto-generated method stub
String actionParams = "";
String url = "";
String method = "";
if (action == RssAction.UnSubscribe)
{
try {
url = "https://cloud.feedly.com/v3/subscriptions/" + URLEncoder.encode(channel.Id,"UTF-8") + "?ck=" + System.currentTimeMillis() + "&ct=feedly.desktop&cv=17.1.614";
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
actionParams = "";
method = "DELETE";
}
if (action == RssAction.RemoveTag)
{
//http://cloud.feedly.com/v3/subscriptions/feed%2Fhttp%3A%2F%2Ffeeds2.feedburner.com%2Fcnbeta-full?ck=1371959857730&ct=feedly.desktop
//DELETE
try {
url = "https://cloud.feedly.com/v3/subscriptions/" + URLEncoder.encode(channel.Id,"UTF-8") + "?ck="+ System.currentTimeMillis() +"&ct=feedly.desktop";
} catch (UnsupportedEncodingException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
actionParams = "";
method = "DELETE";
}
if (action == RssAction.MoveTag)
{
//{"id":"feed/http://feeds2.feedburner.com/cnbeta-full","title":"cnBeta全文版","categories":[{"id":"user/d1ef3938-a54b-4404-9d9d-f97842124281/category/test","label":"test"}]}:
//{"id":"feed/http://www.cnbeta.com/backend.php","title":"cnBeta.COM","categories":[{"id":"user/d1ef3938-a54b-4404-9d9d-f97842124281/category/Test","label":"Test"}]}
String newTitle = String.valueOf(channel.Tag);
if(newTitle.equals("Root"))
actionParams = "{\"id\":\"" + TextUtils.htmlEncode(channel.Id) + "\",\"title\":\"" + TextUtils.htmlEncode(channel.Title) + "\",\"categories\":[]}";
else
actionParams = "{\"id\":\"" + TextUtils.htmlEncode(channel.Id) + "\",\"title\":\"" + TextUtils.htmlEncode(channel.Title) + "\",\"categories\":[{\"id\":\"user/" + ReaderApp.getProfile().Id + "/category/" + newTitle + "\",\"label\":\"" + newTitle + "\"}]}";
url = "http://cloud.feedly.com/v3/subscriptions?ct=feedly.desktop";
method = "POST";
}
if (action == RssAction.Rename)
{
String newTitle = String.valueOf(channel.Tag);
actionParams = "{\"id\":\"" + channel.Id + "\",\"title\":\"" + newTitle + "\",\"categories\":[]}";
url = "http://cloud.feedly.com/v3/subscriptions?ct=feedly.desktop";
method = "POST";
}
if (action == RssAction.AllAsRead)
{
if(channel.IsDirectory)
{
//{"action":"markAsRead","type":"categories","categoryIds":["user/d1ef3938-a54b-4404-9d9d-f97842124281/category/指导"],"asOf":1371898725006}
actionParams = "{\"action\":\"markAsRead\",\"type\":\"categories\",\"categoryIds\":[\"user/" + ReaderApp.getProfile().Id + "/category/" + TextUtils.htmlEncode(channel.Title) + "\"],\"asOf\":" + System.currentTimeMillis() + "}";
url = "http://cloud.feedly.com/v3/markers?ct=feedly.desktop";
}
else
{
//{"action":"markAsRead","type":"feeds","feedIds":["feed/http://www.wpdang.com/feed"],"asOf":1371917583346}
actionParams = "{\"action\":\"markAsRead\",\"type\":\"feeds\",\"feedIds\":[\"" + channel.Id +"\"],\"asOf\":" + System.currentTimeMillis() + "}";
url = "http://cloud.feedly.com/v3/markers?ct=feedly.desktop";
}
method = "POST";
}
url = url + "&ck=" + System.currentTimeMillis();
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
final AsyncHttpResponseHandler async = new AsyncHttpResponseHandler(){
public void onSuccess(String response){
new Thread(){
public void run(){
if (handler != null)
{
handler.sendResponseMessage(action, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successupdatestatus));
}
}
}.start();
}
public void onFailure(final Throwable e, final String response) {
new Thread(){
public void run(){
String error = "";
if(response == null){
error = e.getCause().getMessage();
}else{
error = response;
}
if (error != null && error.contains("expire")){
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
markTag(channel, action, handler);
}else{
if (handler != null){
handler.sendResponseMessage(action, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedupdatestatus));
}
}
}
});
Log.e("RssReader", error);
}
else
{
if (handler != null)
{
handler.sendResponseMessage(action, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedupdatestatus));
}
}
}
}.start();
}
};
if(actionParams.length() == 0)
{
client.addHeader("Content-Type","application/json");
client.addHeader("Content-Length","0");
client.delete(url,async);
}
else
{
StringEntity se = null;
try {
se = new StringEntity(actionParams.toString(),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return;
}
client.post(null, url, se, "application/json",async);
}
}
@Override
public void getRssBlog(final Channel channel, final Blog blog, final int count, final HttpResponseHandler handler) {
String url = "";
try {
if(channel.Id.length() > 0)
url = "https://cloud.feedly.com/v3/streams/contents?streamId=" + URLEncoder.encode(channel.Id, "UTF-8");
else
url = "https://cloud.feedly.com/v3/streams/contents?streamId=" + URLEncoder.encode("user/" + ReaderApp.getProfile().Id + "/category/global.all", "UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
if (blog.TimeStamp > 0)
{
if (Preferences.contains("UP" + channel.Id) && Preferences.getString("UP" + channel.Id,"").length() > 0)
{
url = url + "&count=" + count + "&continuation=" + Preferences.getString("UP" + channel.Id, "") + "&newerThan=" + blog.TimeStamp;
}
else
{
url = url + "&count=" + count;
}
}
else if (blog.TimeStamp < 0)
{
if (Preferences.contains("DOWN" + blog.ChannelId) && Preferences.getString("DOWN" + blog.ChannelId,"").length() > 0)
{
url = url + "&count=" + count + "&continuation=" + Preferences.getString("DOWN" + blog.ChannelId,"");
}
else
{
url = url + "&count=" + count;
}
}
else if (blog.TimeStamp == 0)
{
url = url + "&count=" + count;
}
url = url + "&ct=feedly.desktop&unreadOnly=false&ranked=newest&ck=" + System.currentTimeMillis();
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
Log.i("RssReader", "Start get rss blog request at: " + new Date());
client.get(url, new AsyncHttpResponseHandler(){
@Override
public void onFailure(final Throwable e, final String errorResponse){
new Thread(){
public void run(){
String error = "";
if(errorResponse == null)
error = e.getCause() != null ? e.getCause().getMessage() : e.getMessage();
else
error = errorResponse;
if (error != null && error.contains("expire")){
//now token is expired, we need to relogin
refreshToken(new HttpResponseHandler(){
public void onCallback(String token, boolean result, String msg){
if(result){
getRssBlog(channel, blog, count, handler);
}else{
if (handler != null)
{
handler.sendResponseMessage(new ArrayList<Blog>(), false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetblogs), false);
}
}
}
});
Log.i("RssReader", error);
}
else
{
if (handler != null)
{
handler.sendResponseMessage(new ArrayList<Blog>(), false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetblogs), false);
}
}
}
}.start();
}
@Override
public void onSuccess(final String data){
//get blogs and clean duplicate blogs
new Thread(){
public void run(){
Log.i("RssReader", "Finish get rss blog request at " + new Date());
try{
JSONObject result = new JSONObject(data);
String continuation = !result.has("continuation")
? ""
: result.getString("continuation");
if (blog.TimeStamp > 0)
{
//get lastest
editor.putString("UP" + channel.Id, continuation).commit();
}
else if (blog.TimeStamp <= 0)
{
//get older
editor.putString("DOWN" + channel.Id, continuation).commit();
}
List<Blog> blogs = new ArrayList<Blog>();
JSONArray array = result.getJSONArray("items");
JSONObject item = null;
for(int i = 0; i < array.length(); i++)
{
item = array.getJSONObject(i);
Blog b = new Blog();
b.TagId = "";
b.Content = "";
if (item.has("categories"))
{
JSONObject obj = null;
JSONArray categories = item.getJSONArray("categories");
for(int j = 0; j < categories.length(); j++)
{
obj = categories.getJSONObject(j);
if(obj.getString("id").contains("category"))
{
b.TagId = obj.getString("id");
break;
}
}
//b.TagId = item.get("categories").Children().First(c => c["id"].Value<String>().Contains("category"))["id"].Value<String>();
}
b.BlogId = item.getString("id");
b.ChannelId = item.getJSONObject("origin").getString("streamId");
if(item.has("title"))
b.Title = HtmlHelper.unescape(item.getString("title"));
else
b.Title = HtmlHelper.unescape(item.getJSONObject("origin").getString("title"));
b.Description = ReaderApp.getAppContext().getResources().getString(R.string.empty);
if (item.has("summary"))
b.Description = HtmlHelper.unescape(item.getJSONObject("summary").getString("content"));
if (item.has("content"))
b.Description = HtmlHelper.unescape(item.getJSONObject("content").getString("content"));
if (item.has("alternate")){
int alt = item.getJSONArray("alternate").length();
for(int j=0; j<alt; j++){
if(item.getJSONArray("alternate").getJSONObject(j).has("href"))
b.Link = item.getJSONArray("alternate").getJSONObject(j).getString("href");
if(item.getJSONArray("alternate").getJSONObject(j).has("originId"))
b.Link = item.getString("originId");
if(b.Link.length() > 0)
break;
}
}
//remove cnbeta ad
if (b.Link.contains("cnbeta.com"))
{
int index = b.Description.indexOf("<img");
if (index != -1)
b.Description = b.Description.substring(0, index);
}
b.PubDate = new Date(item.getLong("crawled"));
b.SubsTitle = item.getJSONObject("origin").has("title") ? item.getJSONObject("origin").getString("title") : "";
b.TimeStamp = item.getLong("published");
b.IsRead = item.has("unread") ? !item.getBoolean("unread") : false;
Matcher m = Pattern.compile(IMGURL_REG).matcher(b.Description);
if (m.find()) {
Matcher matcher = Pattern.compile(IMGSRC_REG).matcher(m.group());
while (matcher.find()) {
b.Avatar = matcher.group().substring(0, matcher.group().length() - 1);
}
}
else{
b.Avatar = "";
}
if (item.has("tags"))
{
JSONObject obj = null;
JSONArray tags = item.getJSONArray("tags");
for(int j = 0; j< tags.length();j++)
{
if (tags.getString(j).contains("saved"))
b.IsStarred = true;
}
}
b.OriginId = item.getString("id");
b.IsRecommend = false;
blogs.add(b);
}
//deal with long time no updates
boolean hasMore = true;
for(Blog b : blogs){
long between=(b.PubDate.getTime()- blog.PubDate.getTime())/1000;
if(between > 0L)
hasMore = hasMore && true;
else
hasMore = hasMore && false;
}
if(blog.TimeStamp <= 0L)
hasMore = false;
if(hasMore)
{
if (handler != null)
{
handler.sendResponseMessage(blogs, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_waitformoreblogs), true);
}
getRssBlog(channel, blog, count, handler);
}
else
{
if(blog.TimeStamp > 0)
editor.putString("UP" + channel.Id, "").commit();
if (handler != null)
{
handler.sendResponseMessage(blogs, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successtogetblogs), false);
}
}
}
catch(Exception json){
json.printStackTrace();
if (handler != null)
handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetblogs));
}
}
}.start();
}
});
}
// @Override
// public void getRssBlog(final Channel channel, final Blog blog, final int count, final HttpResponseHandler handler, final int page) {
// String url = "";
// try {
// if(channel.Id.length() > 0)
// url = "https://cloud.feedly.com/v3/streams/contents?streamId=" + URLEncoder.encode(channel.Id, "UTF-8");
// else
// url = "https://cloud.feedly.com/v3/streams/contents?streamId=" + URLEncoder.encode("user/" + ReaderApp.getProfile().Id + "/category/global.all", "UTF-8");
// } catch (UnsupportedEncodingException e1) {
// e1.printStackTrace();
// }
//
// if (blog.TimeStamp > 0)
// {
// if (Preferences.contains("UP" + channel.Id) && Preferences.getString("UP" + channel.Id,"").length() > 0)
// {
// url = url + "&count=" + count + "&continuation=" + Preferences.getString("UP" + channel.Id, "") + "&newerThan=" + blog.TimeStamp;
// }
// else
// {
// url = url + "&count=" + count;
// }
// }
// else if (blog.TimeStamp < 0)
// {
// if (Preferences.contains("DOWN" + blog.ChannelId) && Preferences.getString("DOWN" + blog.ChannelId,"").length() > 0)
// {
// url = url + "&count=" + count + "&continuation=" + Preferences.getString("DOWN" + blog.ChannelId,"");
// }
// else
// {
// url = url + "&count=" + count;
// }
// }
// else if (blog.TimeStamp == 0)
// {
// url = url + "&count=" + count;
// }
//
// url = url + "&ct=feedly.desktop&unreadOnly=false&ranked=newest&ck=" + System.currentTimeMillis();
//
// AsyncHttpClient client = new AsyncHttpClient();
//
// client.addHeader("Host", "cloud.feedly.com");
// client.addHeader("Accept-Charset", "utf8");
// client.addHeader("Referer", "http://cloud.feedly.com/");
// client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
//
// Log.i("RssReader", "Start get rss blog request at: " + new Date());
//
// client.get(url, new AsyncHttpResponseHandler(){
// @Override
// public void onFailure(final Throwable e, final String errorResponse){
// new Thread(){
// public void run(){
// String error = "";
//
// if(errorResponse == null)
// error = e.getCause() != null ? e.getCause().getMessage() : e.getMessage();
// else
// error = errorResponse;
//
// if (error != null && error.contains("expire")){
// //now token is expired, we need to relogin
// refreshToken(new HttpResponseHandler(){
// public void onCallback(String token, boolean result, String msg){
// if(result){
// getRssBlog(channel, blog, count, handler);
// }else{
// if (handler != null)
// {
// handler.sendResponseMessage(new ArrayList<Blog>(), false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetblogs), false, -1);
// }
// }
// }
// });
//
// Log.i("RssReader", error);
// }
// else
// {
// if (handler != null)
// {
// handler.sendResponseMessage(new ArrayList<Blog>(), false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetblogs), false, -1);
// }
// }
// }
// }.start();
// }
//
// @Override
// public void onSuccess(final String data){
// //get blogs and clean duplicate blogs
// new Thread(){
// public void run(){
// Log.i("RssReader", "Finish get rss blog request at " + new Date());
//
// try{
// JSONObject result = new JSONObject(data);
//
// String continuation = !result.has("continuation")
// ? ""
// : result.getString("continuation");
// if (blog.TimeStamp > 0)
// {
// //get lastest
// editor.putString("UP" + channel.Id, continuation).commit();
// }
// else if (blog.TimeStamp <= 0)
// {
// //get older
// editor.putString("DOWN" + channel.Id, continuation).commit();
// }
//
// List<Blog> blogs = new ArrayList<Blog>();
// JSONArray array = result.getJSONArray("items");
// JSONObject item = null;
// for(int i = 0; i < array.length(); i++)
// {
// item = array.getJSONObject(i);
//
// Blog b = new Blog();
//
// b.TagId = "";
// b.Content = "";
// if (item.has("categories"))
// {
// JSONObject obj = null;
// JSONArray categories = item.getJSONArray("categories");
// for(int j = 0; j < categories.length(); j++)
// {
// obj = categories.getJSONObject(j);
//
// if(obj.getString("id").contains("category"))
// {
// b.TagId = obj.getString("id");
// break;
// }
// }
// //b.TagId = item.get("categories").Children().First(c => c["id"].Value<String>().Contains("category"))["id"].Value<String>();
// }
// b.BlogId = item.getString("id");
// b.ChannelId = item.getJSONObject("origin").getString("streamId");
//
// if(item.has("title"))
// b.Title = HtmlHelper.unescape(item.getString("title"));
// else
// b.Title = HtmlHelper.unescape(item.getJSONObject("origin").getString("title"));
//
// b.Description = ReaderApp.getAppContext().getResources().getString(R.string.empty);
//
// if (item.has("summary"))
// b.Description = HtmlHelper.unescape(item.getJSONObject("summary").getString("content"));
// if (item.has("content"))
// b.Description = HtmlHelper.unescape(item.getJSONObject("content").getString("content"));
// if (item.has("alternate")){
// int alt = item.getJSONArray("alternate").length();
// for(int j=0; j<alt; j++){
// if(item.getJSONArray("alternate").getJSONObject(j).has("href"))
// b.Link = item.getJSONArray("alternate").getJSONObject(j).getString("href");
// if(item.getJSONArray("alternate").getJSONObject(j).has("originId"))
// b.Link = item.getString("originId");
//
// if(b.Link.length() > 0)
// break;
// }
// }
//
// //remove cnbeta ad
// if (b.Link.contains("cnbeta.com"))
// {
// int index = b.Description.indexOf("<img");
// if (index != -1)
// b.Description = b.Description.substring(0, index);
// }
//
// b.PubDate = new Date(item.getLong("crawled"));
// b.SubsTitle = item.getJSONObject("origin").has("title") ? item.getJSONObject("origin").getString("title") : "";
// b.TimeStamp = item.getLong("published");
// b.IsRead = item.has("unread") ? !item.getBoolean("unread") : false;
// b.Avatar = "";
//
// if (item.has("tags"))
// {
// JSONObject obj = null;
// JSONArray tags = item.getJSONArray("tags");
// for(int j = 0; j< tags.length();j++)
// {
// if (tags.getString(j).contains("saved"))
// b.IsStarred = true;
// }
// }
//
// b.OriginId = item.getString("id");
// b.IsRecommend = false;
//
// blogs.add(b);
// }
//
// //deal with long time no updates
// boolean hasMore = true;
// for(Blog b : blogs){
// long between=(b.PubDate.getTime()- blog.PubDate.getTime())/1000;
//
// if(between > 0L)
// hasMore = hasMore && true;
// else
// hasMore = hasMore && false;
// }
//
// if(blog.TimeStamp <= 0L)
// hasMore = false;
//
// if(hasMore)
// {
// if (handler != null)
// {
// if(page == -1)
// handler.sendResponseMessage(blogs, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_waitformoreblogs), true, page);
// else{
//
// handler.sendResponseMessage(blogs, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_waitformoreblogs), true, page);
// }
// }
//
// int temp = page;
// temp++;
//
// getRssBlog(channel, blog, count, handler, temp);
// }
// else
// {
// if(blog.TimeStamp > 0)
// editor.putString("UP" + channel.Id, "").commit();
//
// if (handler != null)
// {
// handler.sendResponseMessage(blogs, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successtogetblogs), false, page);
// }
// }
// }
// catch(Exception json){
// json.printStackTrace();
// if (handler != null)
// handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedtogetblogs));
// }
// }
// }.start();
// }
// });
// }
@Override
public void getFavor(String tag, Blog b, int count, HttpResponseHandler handler) {
Channel c = new Channel();
c.Id = "user/" + ReaderApp.getProfile().Id + "/tag/" + tag;
getRssBlog(c, b, count, handler);
}
@Override
public void addRss(final String rssUrl, String searchResultTitle, final HttpResponseHandler handler) {
String actionParams = "";
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
actionParams = "{\"id\":\"" + rssUrl + "\",\"title\":\"" + searchResultTitle + "\",\"categories\":[]}";
String url = "http://cloud.feedly.com/v3/subscriptions?ck=" + System.currentTimeMillis() + "&ct=feedly.desktop&cv=16.0.548";
ByteArrayEntity entity = null;
try {
entity = new ByteArrayEntity(actionParams.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
client.post(null, url, entity, "application/json", new AsyncHttpResponseHandler(){
@Override
public void onFailure(final Throwable e, final String response) {
// Response failed :(
new Thread(){
public void run(){
String error = "";
if(response == null){
error = e.getCause().getMessage();
}else{
error = response;
}
if (error != null && error.contains("expire")){
//now token is expired, we need to relogin
if (handler != null)
{
handler.sendResponseMessage(rssUrl, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_sessionexpire));
}
Log.i("RssReader", error);
}
else
{
if (handler != null)
{
handler.sendResponseMessage(rssUrl, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedaddsubscription));
}
}
}
}.start();
}
@Override
public void onSuccess(String data){
new Thread(){
public void run(){
if(handler != null)
handler.sendResponseMessage(rssUrl, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successaddsubscription));
}
}.start();
}
});
}
@Override
public void assignFolder(final Channel folder, Channel single, final HttpResponseHandler handler) {
String actionParams = "";
// Means new folder
if (folder.SortId.length() != 0)
{
//new folder
actionParams = "{\"id\":\"" + single.Id + "\",\"title\":\"" + single.Title + "\",\"categories\":[{\"id\":\"user/" + ReaderApp.getProfile().Id + "/category/" + folder.Title + "\",\"label\":\"" + folder.Title + "\"}]}";
}
if (folder.Title.length() == 0)
{
actionParams = "{\"id\":\"" + single.Id + "\",\"title\":\"" + single.Title + "\",\"categories\":[]}";
}
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
StringEntity se = null;
try {
se = new StringEntity(actionParams.toString(),"UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return;
}
String url = "http://cloud.feedly.com/v3/subscriptions?ct=feedly.desktop&ck=" + System.currentTimeMillis();
client.post(null, url, se, "application/json", new AsyncHttpResponseHandler(){
@Override
public void onFailure(final Throwable t, final String result){
new Thread(){
public void run(){
String error = "";
if(result == null)
error = t.getCause().getMessage();
else
error = result;
//Log.i("RssReader", error);
if (error != null && error.contains("expire"))//now token is expired, we need to relogin
handler.sendResponseMessage(false, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_sessionexpire));
else
handler.sendResponseMessage(false, false, String.format(ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedmovefolder), folder.Title));
}
}.start();
}
@Override
public void onSuccess(String reponse){
new Thread(){
public void run(){
handler.sendResponseMessage(true, true, String.format(ReaderApp.getAppContext().getResources().getString(R.string.feedly_successmovefolder), folder.Title));
}
}.start();
}
});
}
@Override
public void searchRss(String key, int page, final HttpResponseHandler handler) {
AsyncHttpClient client = new AsyncHttpClient();
client.addHeader("Host", "cloud.feedly.com");
client.addHeader("Accept-Charset", "utf8");
client.addHeader("Referer", "http://cloud.feedly.com/");
client.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
String url = "";
try {
url = "http://www.feedly.com/v3/search/feeds?q=" + URLEncoder.encode(key, "UTF-8") + "&n=20&d=true&ck=" + System.currentTimeMillis();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
client.get(url, new JsonHttpResponseHandler(){
@Override
public void onFailure(final Throwable t, final String result){
new Thread(){
public void run(){
String error = "";
if(result == null)
error = t.getCause().getMessage();
else
error = result;
//Log.i("RssReader", error);
if(error.contains("session"))
handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_sessionexpire), false);
else
handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedsearch), false);
}
}.start();
}
@Override
public void onSuccess(final JSONObject obj){
new Thread(){
public void run(){
List<Result> results = new ArrayList<Result>();
try{
JSONObject r = null;
int len = obj.getJSONArray("results").length();
for(int i=0; i<len;i++){
r = obj.getJSONArray("results").getJSONObject(i);
Result result = new Result();
result.IsSubscribed = false;
result.Title = r.getString("title");
result.StreamId = r.getString("feedId");
result.SubscriptCount = r.getString("subscribers");
results.add(result);
}
if(len > 0)
handler.sendResponseMessage(results, true, ReaderApp.getAppContext().getResources().getString(R.string.feedly_successsearch), false);
else
handler.sendResponseMessage(null, false, ReaderApp.getAppContext().getResources().getString(R.string.feedly_failedsearch), false);
}catch(JSONException je){
je.printStackTrace();
}
}
}.start();
}
});
}
@Override
public void asyncDownload(Channel c, int count, HttpResponseHandler handler) {
}
/*
* This method is used in DownloadTask, it works in background and should be synchronous
* So we don't use AsyncHttpClient to make http request, we use default HttpClient instead.
*/
@Override
public List<Blog> syncDownload(Channel c, int count) {
String url = "";
List<Blog> blogs = new ArrayList<Blog>();
try {
if(c.Id.length() > 0)
url = "https://cloud.feedly.com/v3/streams/contents?streamId=" + URLEncoder.encode(c.Id, "UTF-8");
if(ReaderApp.getProfile() != null && ReaderApp.getProfile().Id.length() > 0)
url = "https://cloud.feedly.com/v3/streams/contents?streamId=" + URLEncoder.encode("user/" + ReaderApp.getProfile().Id + "/category/global.all", "UTF-8");
} catch (UnsupportedEncodingException e1) {
e1.printStackTrace();
}
if(url.length() == 0)
return blogs;
url = url + "&count=" + count + "&ct=feedly.desktop&unreadOnly=false&ranked=newest&ck=" + System.currentTimeMillis();
HttpGet httpRequest = new HttpGet(url);
httpRequest.addHeader("Host", "cloud.feedly.com");
httpRequest.addHeader("Accept-Charset", "utf8");
httpRequest.addHeader("Referer", "http://cloud.feedly.com/");
httpRequest.addHeader("X-Feedly-Access-Token", ReaderApp.getToken(Token.AccessToken));
//取得HttpClient对象
HttpClient httpclient = new DefaultHttpClient();
HttpResponse response;
try {
response = httpclient.execute(httpRequest);
if(response.getStatusLine().getStatusCode() == HttpStatus.SC_OK){
//取得返回的字符串
String data = EntityUtils.toString(response.getEntity());
JSONObject result = new JSONObject(data);
JSONArray array = result.getJSONArray("items");
JSONObject item = null;
for(int i = 0; i < array.length(); i++)
{
item = array.getJSONObject(i);
Blog b = new Blog();
b.TagId = "";
b.Content = "";
if (item.has("categories"))
{
JSONObject obj = null;
JSONArray categories = item.getJSONArray("categories");
for(int j = 0; j < categories.length(); j++)
{
obj = categories.getJSONObject(j);
if(obj.getString("id").contains("category"))
{
b.TagId = obj.getString("id");
break;
}
}
//b.TagId = item.get("categories").Children().First(c => c["id"].Value<String>().Contains("category"))["id"].Value<String>();
}
b.BlogId = item.getString("id");
b.ChannelId = item.getJSONObject("origin").getString("streamId");
b.Title = HtmlHelper.unescape(item.getString("title"));
if (item.has("summary"))
b.Description = HtmlHelper.unescape(item.getJSONObject("summary").getString("content"));
else
b.Description = HtmlHelper.unescape(item.getJSONObject("content").getString("content"));
if (item.has("alternate")){
int alt = item.getJSONArray("alternate").length();
for(int j=0; j<alt; j++){
if(item.getJSONArray("alternate").getJSONObject(j).has("href"))
b.Link = item.getJSONArray("alternate").getJSONObject(j).getString("href");
if(item.getJSONArray("alternate").getJSONObject(j).has("originId"))
b.Link = item.getString("originId");
if(b.Link.length() > 0)
break;
}
}
//remove cnbeta ad
if (b.Link.contains("cnbeta.com"))
{
int index = b.Description.indexOf("<img");
if (index != -1)
b.Description = b.Description.substring(0, index);
}
b.PubDate = new Date(item.getLong("published"));
b.SubsTitle = item.getJSONObject("origin").getString("title");
b.TimeStamp = item.getLong("crawled");
b.IsRead = !item.getBoolean("unread");
b.Avatar = "";
if (item.has("tags"))
{
JSONObject obj = null;
JSONArray tags = item.getJSONArray("tags");
for(int j = 0; j< tags.length();j++)
{
if (tags.getString(j).contains("saved"))
b.IsStarred = true;
}
}
b.OriginId = item.getString("id");
b.IsRecommend = false;
blogs.add(b);
}
}
}
catch(JSONException json){
json.printStackTrace();
}
catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (ClientProtocolException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return blogs;
}
}